根据属性将对象数组分解为单独的数组

IT技术 javascript jquery arrays object underscore.js
2021-03-08 14:19:54

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

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

6个回答

这是一项轻松的工作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;
}
@TravisJ:是的,是的,如果您的目标浏览器不支持 EMCAScript 262 第 5 版,那么您需要实现自己的“减少”功能或选择其他答案之一。
2021-04-17 14:19:54
可能还想包含一个兼容更多浏览器的版本。reduceIE8- 不支持。
2021-05-03 14:19:54

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

Underscore 的groupBy功能正是您所需要的。

_.groupBy(arr, "type")

这假设一个对象数组:

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

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

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/

效果很好,也感谢将模式称为字典!
2021-04-19 14:19:54

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

我希望它有帮助!

仅供参考:调用此函数时,属性参数应为字符串。
2021-05-14 14:19:54