【问题标题】:break array of objects into separate arrays based on a property根据属性将对象数组分解为单独的数组
【发布时间】:2013-01-19 17:14:30
【问题描述】:

假设我有一个这样的数组:

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 和 Underscore 都是可以使用的选项。

【问题讨论】:

  • 感谢您提供非常有用的回复。更改了等号。

标签: javascript jquery arrays object underscore.js


【解决方案1】:

这假定一个对象数组:

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]}

【讨论】:

    【解决方案2】:

    只需构建一个字典,根据它们的标题保存对象。你可以这样做:

    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/

    【讨论】:

    • 效果很好,也感谢将模式称为字典!
    【解决方案3】:

    这对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”,或者使用 polyfill 库,或者选择其他答案。

    [更新]这是一个适用于任何 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;
    }
    

    【讨论】:

    • 可能还想包含一个兼容更多浏览器的版本。 IE8 不支持reduce
    • @TravisJ:是的,是的,如果您的目标浏览器不支持 EMCAScript 262 第 5 版,那么您需要实现自己的“减少”功能或选择其他答案之一。跨度>
    【解决方案4】:

    JQuery 和 Underscore 都是可以使用的选项。

    Underscore's groupBy 完全满足您的需求。

    _.groupBy(arr, "type")
    

    【讨论】:

      【解决方案5】:

      打字稿版本。

      /**
      * 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;
      

      【讨论】:

        【解决方案6】:

        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;
            }, {});
        }
        

        希望对你有帮助!

        【讨论】:

        • 仅供参考:调用该函数时,property参数应为字符串。
        【解决方案7】:

        你也可以使用 https://lodash.com/docs/4.17.15#groupBy

        它会达到你的目的

        【讨论】:

          猜你喜欢
          • 2018-07-30
          • 1970-01-01
          • 2019-05-29
          • 2020-02-22
          • 1970-01-01
          • 1970-01-01
          • 2022-01-18
          • 2018-10-07
          • 2013-05-01
          相关资源
          最近更新 更多