javascript | 对象分组

use*_*349 13 javascript merge grouping object

我有一个对象.它看起来如下:

[
  {
    "name":"Display",
    "group":"Technical detals",
    "id":"60",
    "value":"4"
  },
  {
    "name":"Manufacturer",
    "group":"Manufacturer",
    "id":"58",
    "value":"Apple"
  },
  {
    "name":"OS",
    "group":"Technical detals",
    "id":"37",
    "value":"Apple iOS"
  }
]
Run Code Online (Sandbox Code Playgroud)

我想按组字段对这些数据进行分组并获取此对象:

var obj = {
    0 = [
    {
       'group'   = 'Technical detals',
       'name'    = 'Display',
       'id'      = '60',
       'value'   = '4'
    },
    {
       'group'   = 'Technical detals',
       'name'    = 'OS',
       'id'      = '37',
       'value'   = 'Apple iOS'
    }],
    1   = [
    {
       'group'   = 'Manufacturer',
       'name'    = 'Manufacturer',
       'id'      = '58',
       'value'   = 'Apple'
    }]
}
Run Code Online (Sandbox Code Playgroud)

如何分组我的第一个对象?

Max*_*Art 21

试试这样的事情:

function groupBy(collection, property) {
    var i = 0, val, index,
        values = [], result = [];
    for (; i < collection.length; i++) {
        val = collection[i][property];
        index = values.indexOf(val);
        if (index > -1)
            result[index].push(collection[i]);
        else {
            values.push(val);
            result.push([collection[i]]);
        }
    }
    return result;
}

var obj = groupBy(list, "group");
Run Code Online (Sandbox Code Playgroud)

请记住,Array.prototype.indexOfIE8及更早版本中未定义,但有常见的polyfill.

  • 我知道这是旧的,但我认为有些人可能会偶然发现这一点,并且希望必须将分组值作为键,使用相同的函数只需修改 if else 部分,如下所示: `if (index &gt; -1) result[val ].push(集合[i]); else { 值.push(val); 结果[值] = []; 结果[val].push([集合[i]]); }` (2认同)

Ant*_*ley 11

使用reducefilter

假设您的初始数组分配给 data

data.reduce((acc, d) => {
    if (Object.keys(acc).includes(d.group)) return acc;

    acc[d.group] = data.filter(g => g.group === d.group); 
    return acc;
}, {})
Run Code Online (Sandbox Code Playgroud)

这会给你类似的东西

{
    "Technical detals" = [
    {
       'group'   = 'Technical detals',
       'name'    = 'Display',
       'id'      = '60',
       'value'   = '4'
    },
    {
       'group'   = 'Technical detals',
       'name'    = 'OS',
       'id'      = '37',
       'value'   = 'Apple iOS'
    }],
    "Manufacturer"   = [
    {
       'group'   = 'Manufacturer',
       'name'    = 'Manufacturer',
       'id'      = '58',
       'value'   = 'Apple'
    }]
}
Run Code Online (Sandbox Code Playgroud)


ppo*_*ani 10

如果您在应用程序中使用underscore.js,则只需执行以下操作:

var groups = _.groupBy(data, 'group'); // data is your initial collection
Run Code Online (Sandbox Code Playgroud)

或者,如果您不想使用任何库,那么您可以自己完成:

var groups = { };
data.forEach(function(item){
   var list = groups[item.group];

   if(list){
       list.push(item);
   } else{
      groups[item.group] = [item];
   }
});
Run Code Online (Sandbox Code Playgroud)

您可以在http://jsfiddle.net/nkVu6/3/中看到这两个示例


tri*_*cot 9

如果您喜欢使用ES6 Map,那么适合您:

function groupBy(arr, prop) {
    const map = new Map(Array.from(arr, obj => [obj[prop], []]));
    arr.forEach(obj => map.get(obj[prop]).push(obj));
    return Array.from(map.values());
}

const data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
	
console.log(groupBy(data, "group"));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

Map实例是从由输入阵列所产生的键/值对创建的。键是要分组的属性的值,并且这些值被初始化为空数组。

然后填充这些数组。最后,返回映射的值(即那些填充的数组)。


Nin*_*olz 6

您可以将哈希表用于组和Array#forEach迭代数组。

然后检查哈希是否存在,如果不存在,则为它分配一个空数组,然后将其推入结果集中。

稍后将实际元素推入哈希数组。

function groupBy(array, group) {
    var hash = Object.create(null),
        result = [];

    array.forEach(function (a) {
        if (!hash[a[group]]) {
            hash[a[group]] = [];
            result.push(hash[a[group]]);
        }
        hash[a[group]].push(a);
    });
    return result;
}

var data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
	
console.log(groupBy(data, "group"));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

  • @ApoloRadomer,如果这对您有用,那就太好了。 (2认同)

bto*_*omw 5

在这种情况下,Reducing非常有用。鉴于list以下是输入数据:

const list = [{
    'name': 'Display',
    'group': 'Technical detals',
    'id': '60',
    'value': '4'
  },
  {
    'name': 'Manufacturer',
    'group': 'Manufacturer',
    'id': '58',
    'value': 'Apple'
  },
  {
    'name': 'OS',
    'group': 'Technical detals',
    'id': '37',
    'value': 'Apple iOS'
  }
];

const groups = list.reduce((groups, item) => {
  const group = (groups[item.group] || []);
  group.push(item);
  groups[item.group] = group;
  return groups;
}, {});

console.log(groups);
Run Code Online (Sandbox Code Playgroud)

如果您想保持不变,则可以这样编写reduce

const list = [{
    'name': 'Display',
    'group': 'Technical detals',
    'id': '60',
    'value': '4'
  },
  {
    'name': 'Manufacturer',
    'group': 'Manufacturer',
    'id': '58',
    'value': 'Apple'
  },
  {
    'name': 'OS',
    'group': 'Technical detals',
    'id': '37',
    'value': 'Apple iOS'
  }
];

const groups = list.reduce((groups, item) => ({
  ...groups,
  [item.group]: [...(groups[item.group] || []), item]
}), {});

console.log(groups);
Run Code Online (Sandbox Code Playgroud)

取决于您的环境是否允许传播语法。