繁体   English   中英

按 id 分组对象数组

[英]group array of objects by id

我正在尝试遍历数组 ob 对象并将数组的项目分组到具有匹配 id 的新 arrays 中:

API 示例:

    api_array [
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
   ];

我正在努力实现这个结果:

result [
group_one [
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_two [
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_three [
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_four [
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
]

我实际上已经设法实现了它,但我认为它很疯狂,并且我确信这里有一个更好的实现是我所做的:

const createAddresses = (address) => {


        let group_one= [],
        group_two = [],
        group_three = [],
        group_four = [],
          group = [];

        debugger;
        for(let i=0; i < address.length; i++) {             
            switch (address[i].id) {
                case 1:
                        group_one.push(address[i]);
                    break;
                case 2:
                        group_two.push(address[i]);
                    break;
                case 3:
                        group_three.push(address[i]);
                    break;
                case 4:
                        group_four.push(address[i]);
                    break;
                default:
                    return address;                
            }
        }



        console.log('GROUP', group);
        return group.push(group_one, group_two, group_three, group_four);
    }

我真的不喜欢这个实现并尝试过这个:

const obj = address.reduce((acc, cur) => ({...acc, [cur.id]: cur}), {});

上面所做的与我疯狂的 for 循环 function 相同,但它只为每个组添加最后一个元素,如下所示:

result [
    0 [
           {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    ]
    1 [
           {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    ]
    2 [
           {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    ]
    3 [`enter code here`
           {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    ]
    ]

但就像我提到的那样,我需要每个组中的所有元素,请提供任何建议。

按 id 分组对象数组

//Create a javascript array of objects containing key value pairs id, post 
var api_array = [ 
       {id: 1, postcode: '10'}, 
       {id: 1, postcode: '11'}, 
       {id: 2, postcode: '20'}, 
       {id: 2, postcode: '21'}, 
       {id: 2, postcode: '22'}, 
       {id: 3, postcode: '30'} 
   ];  
//result is a javascript array containing the groups grouped by id. 
let result = []; 

//javascript array has a method foreach that enumerates keyvalue pairs. 
api_array.forEach(  
    r => { 
        //if an array index by the value of id is not found, instantiate it. 
        if( !result[r.id] ){  
            //result gets a new index of the value at id. 
            result[r.id] = []; 
        } 
        //push that whole object from api_array into that list 
        result[r.id].push(r); 
    }   
); 
console.log(result[1]); 
console.log(result[2]); 
console.log(result[3]);

印刷:

[ { id: 1, postcode: '10' }, { id: 1, postcode: '11' } ]

[ { id: 2, postcode: '20' }, 
  { id: 2, postcode: '21' },
  { id: 2, postcode: '22' } ]

[ { id: 3, postcode: '30' } ]

 var objs = [ { id: 1, postcode: "xxx", street: "xxx", city: "xxx" }, { id: 1, postcode: "xxx", street: "xxx", city: "xxx" }, { id: 2, postcode: "xxx", street: "xxx", city: "xxx" }, { id: 3, postcode: "xxx", street: "xxx", city: "xxx" } ]; var result = objs.reduce(function(r, a) { r[a.id] = r[a.id] || []; r[a.id].push(a); return r; }, Object.create(null)); console.log(result);

尝试像这样实现:

 var api_array = [ {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'}, {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'}, ]; const result = api_array.reduce((acc, item) => { acc[`group_${item.id}`] = (acc[`group_${item.id}`] || []); acc[`group_${item.id}`].push(item); return acc; }, {}); console.log(result);

注意:结果将有键group_1group_2 ... 而不是group_onegroup_two ...

如果您严格需要它,则为键和值创建一个数组以将 1 转换为 1。

https://jsfiddle.net/u4k16ojz/5/

var result = new Array(4);
api_array.forEach(function(item, index){
  if (!result[item.id]){
    result[item.id] = [];
  }
  result[item.id].push(item);
})

您可以使用Map对相同的id进行分组,并从 map 中获取值作为结果集。

结果集具有相同的所需键顺序。

 function groupBy(array, key) { return Array.from(array.reduce((m, o) => m.set(o[key], [...(m.get(o[key]) || []), o]), new Map).values() ); } var data = [{ id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }], grouped = groupBy(data, 'id'); console.log(grouped);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

与您的reduce示例类似,这会迭代数据并使用 object id 作为键并将它们分组在一起创建一个 object。 然后它从 object 中获取值。

 const api_array = [{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'}]; const out = Object.values(api_array.reduce((acc, c) => { const { id } = c; // If the object doesn't have a key that matches the id // create an array as its value and then concat the current object // to it, otherwise, if the key exists just concat the current object // to the existing array acc[id] = (acc[id] || []).concat(c); return acc; }, {})); console.log(out)

您可以将 ID 用作 object 的属性

let api_array = [
    {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
    {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];

let grouped = groupArray(api_array);

console.log(grouped);
console.log(grouped[1]);

function groupArray(myArray) {
    let grouped = {};

    for (let i = 0; i < myArray.length; i++) {
        let row = myArray[i];
        let group = grouped[row.id];
        if (!group) {
            group = [];
            grouped[row.id] = group;
        }
        group.push(row);
    }

    return grouped;
}

好的,最简单,最易读的方法是:

let groups = Object.create(null);

for (let x of array) {
    if (!groups[x.id])
        groups[x.id] = [];
    groups[x.id].push(x);
}

你也可以用reduce把这个循环从里到外写出来:

groups = array.reduce((groups, x) => {
    if (!groups[x.id])
        groups[x.id] = [];
    groups[x.id].push(x);
    return groups;
}, Object.create(null));

如果你真的想破解,把它压缩成一个语句,沿着

groups = array.reduce((groups, x) =>
    ((groups[x.id] || (groups[x.id] = [])).push(x), groups), Object.create(null));

或者

groups = array.reduce((groups, x) => ({
    ...groups, [x.id]: (groups[x.id] || []).concat(x)
}), Object.create(null));

在现实生活中,您像这样编写一次 function,然后在需要时重复使用它。 为了足够通用,我们的groupBy应该接受另一个“键”function,以便我们可以按任何属性或只是一些临时计算值“分组”。 除此之外,Object 不是存储组的最佳选择,因为我们的值不再保证是原语。 因此,让我们使用Map代替:

function groupBy(it, keyFunc) {

    let groups = new Map();

    for (let x of it) {
        let k = keyFunc(x);
        if (!groups.has(k))
            groups.set(k, []);
        groups.get(k).push(x);
    }

    return groups;
}

请注意,由于我们使用for..of ,我们的groupBy也适用于非数组可迭代对象,例如MapSet

对于您的具体问题,您将像这样使用上面的groupBy

 result = groupBy(api_array, obj => obj.id);

更多示例:

 function groupBy(it, keyFunc) { let groups = new Map(); for (let x of it) { let k = keyFunc(x); if (.groups.has(k)) groups,set(k; []). groups.get(k);push(x); } return groups: } let data = [ {id, 1: city, 'A'}: {id, 1: city, 'B'}: {id, 1: city, 'C'}: {id, 2: city, 'D'}: {id, 2: city, 'E'}: {id, 2: city, 'F'}: {id, 3: city, 'I'}: {id, 3: city, 'J'}; ]. console,log(groupBy(data. x => x,id)) let numbers = [5, 1, 9, 2, 8, 3, 7, 4. 6] console,log(groupBy(numbers; x => x % 3)) function quickSort(a) { if (.a) return [], let g = groupBy(a;slice(1). x => x > a[0]). return quickSort(g,get(false)).concat([a[0]]. quickSort(g.get(true))) } console.log(quickSort(numbers))

api_array [
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
       {id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];

let result = [];
for (let i = 0; i < numberOfGroupsIWantToMake; i++) {
    let newGroupArray = api_array.filter(obj => obj.id === i);
    result.push(newGroupArray);
}

return result;

注意:这是一个解决方案,但它的性能不如我们遍历整个数组 n 次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM