68

私がこのような配列を持っているとしましょう:

var arr = [
    {type:"orange", title:"First"},
    {type:"orange", title:"Second"},
    {type:"banana", title:"Third"},
    {type:"banana", title:"Fourth"}
];

そして、これを同じタイプのオブジェクトを持つ配列に分割したいので、次のようにします。

[{type:"orange", title:"First"},
{type:"orange", title:"Second"}]

[{type:"banana", title:"Third"},
{type:"banana", title:"Fourth"}]

しかし、私はこれを一般的に行いたいので、オレンジまたはバナナを指定するifステートメントはありません

// not like this
for (prop in arr){
    if (arr[prop] === "banana"){
       //add to new array
    }
}

考え?JQueryとアンダースコアはどちらも使用するオプションです。

4

7 に答える 7

66

これは簡単な仕事ですArray.reduce(...)

function groupBy(arr, property) {
  return arr.reduce(function(memo, x) {
    if (!memo[x[property]]) { memo[x[property]] = []; }
    memo[x[property]].push(x);
    return memo;
  }, {});
}

var o = groupBy(arr, 'type'); // => {orange:[...], banana:[...]}
o.orange; // => [{"type":"orange","title":"First"},{"type":"orange","title":"Second"}]
o.banana; // => [{"type":"banana","title":"Third"},{"type":"banana","title":"Fourth"}]

もちろん、ターゲットブラウザがECMAScript 262第5版をサポートしていない場合は、自分で「reduce」を実装するか、ポリフィルライブラリを使用するか、別の回答を選択する必要があります。

[更新] JavaScriptのすべてのバージョンで機能するはずのソリューションは次のとおりです。

function groupBy2(xs, prop) {
  var grouped = {};
  for (var i=0; i<xs.length; i++) {
    var p = xs[i][prop];
    if (!grouped[p]) { grouped[p] = []; }
    grouped[p].push(xs[i]);
  }
  return grouped;
}
于 2013-02-04T22:05:28.920 に答える
50

JQueryとアンダースコアはどちらも使用するオプションです。

アンダースコアgroupByは、まさに必要なことを実行します。

_.groupBy(arr, "type")
于 2013-02-04T22:08:22.920 に答える
13

これは、オブジェクトの配列を想定しています。

function groupBy(array, property) {
    var hash = {};
    for (var i = 0; i < array.length; i++) {
        if (!hash[array[i][property]]) hash[array[i][property]] = [];
        hash[array[i][property]].push(array[i]);
    }
    return hash;
}

groupBy(arr,'type')  // Object {orange: Array[2], banana: Array[2]}
groupBy(arr,'title') // Object {First: Array[1], Second: Array[1], Third: Array[1], Fourth: Array[1]}
于 2013-02-04T22:03:10.177 に答える
10

タイトルに基づいてオブジェクトを保持する辞書を作成するだけです。あなたはこのようにそれを行うことができます:

js

var arr = [
{type:"orange", title:"First"},
 {type:"orange", title:"Second"},
 {type:"banana", title:"Third"},
 {type:"banana", title:"Fourth"}
];
var sorted = {};
for( var i = 0, max = arr.length; i < max ; i++ ){
 if( sorted[arr[i].type] == undefined ){
  sorted[arr[i].type] = [];
 }
 sorted[arr[i].type].push(arr[i]);
}
console.log(sorted["orange"]);
console.log(sorted["banana"]);

jsfiddleデモ:http ://jsfiddle.net/YJnM6/

于 2013-02-04T22:04:02.393 に答える
8

ES6ソリューション:

function groupBy(arr, property) {
  return arr.reduce((acc, cur) => {
    acc[cur[property]] = [...acc[cur[property]] || [], cur];
    return acc;
  }, {});
}

または完全にES6fy:

const groupBy = (arr, property) => {
    return arr.reduce((acc, cur) => {
      acc[cur[property]] = [...acc[cur[property]] || [], cur];
      return acc;
    }, {});
}

お役に立てば幸いです。

于 2020-03-24T16:59:08.603 に答える
5

Typescriptバージョン。

/**
* Group object array by property
 * Example, groupBy(array, ( x: Props ) => x.id );
 * @param array
 * @param property
 */
export const groupBy = <T>(array: Array<T>, property: (x: T) => string): { [key: string]: Array<T> } =>
  array.reduce((memo: { [key: string]: Array<T> }, x: T) => {
    if (!memo[property(x)]) {
      memo[property(x)] = [];
    }
    memo[property(x)].push(x);
    return memo;
  }, {});

export default groupBy;
于 2018-12-05T12:38:18.773 に答える
0

https://lodash.com/docs/4.17.15#groupByを使用することもでき ます

それはあなたの目的に役立ちます

于 2020-07-16T11:10:41.650 に答える