如何按相同的值重组对象?

问题描述 投票:0回答:4

我有3个对象

[
{name: 3, q: 10, b: 1},
{name: 5, q: 6, b: 2},
{name: 5, q: 7, b: 1}
]

我需要按名称对它们进行分组:

[
{name: 3: items: [{q:10, b: 1}]},
{name: 5: items: [{q:6, b: 2}, {q:7, b: 1}]},
]

也许 lodash 有任何微妙的解决方案?

javascript arrays lodash
4个回答
3
投票

您可以使用 Object.values 结合 Array.prototype.reduce()Array.prototype.push()

代码:

const data = [
  { name: 3, q: 10, b: 1 },
  { name: 5, q: 6, b: 2 },
  { name: 5, q: 7, b: 1 },
]

const groupedData = Object.values(
  data.reduce((acc, obj) => {
    const { name, ...rest } = obj
    acc[name] = acc[name] || { name, items: [] }
    acc[name].items.push(rest)
    return acc
  }, {})
)

console.log(groupedData)


2
投票

你不需要lodash,你可以只使用JavaScript

const inputArray = [
  {name: 3, q: 10, b: 1},
  {name: 5, q: 6, b: 2},
  {name: 5, q: 7, b: 1}
];

使用forEach

function groupItemsByName(array) {
  // create a groups to store your new items
  const groups = {};
  
  //loop through your array
  array.forEach(obj => {
    // destructure each object into name and the rest 
    const { name, ...rest } = obj;
    // if the named group doesnt exist create that name with an empty array
    if (!groups[name]) {
      groups[name] = { name, items: [] };
    }
    // add the items to the named group based on the name
    groups[name].items.push(rest);
  });

  return Object.values(groups);
}

const transformedArray = groupItemsByName(inputArray);

使用 reduceObject.values()

function groupItemsByName(array) {
  //Object.values returns an objects values as an array  
  return Object.values(
    array.reduce((groups, obj) => {
      // destructure as in the forEach method
      const { name, ...rest } = obj;
      // create the groups like in the previous method
      groups[name] = groups[name] || { name, items: [] };
      // push the items to the group based on the name
      groups[name].items.push(rest);
      return groups;
    }, {})
  );
}


const transformedArray = groupItemsByName(inputArray);

使用map和reduce

const transformedArray = Array.from(
  inputArray.reduce((map, obj) => {
    const { name, ...rest } = obj;
    const existing = map.get(name) || { name, items: [] };
    existing.items.push(rest);
    return map.set(name, existing);
  }, new Map()).values()
);

输出

console.log(transformedArray);

0
投票

您可以使用以下简单的解决方案来实现这一点。

const originalArr = [//This is your original input array
    { name: 3, q: 10, b: 1 },
    { name: 5, q: 6, b: 2 },
    { name: 5, q: 7, b: 1 }
];
let filteredArr = [];
originalArr.forEach(el => {
    const index = filteredArr.findIndex(__el => __el.name == el.name);
    if (index == -1) {//This means the current element does not exists in filtered array
        filteredArr.push({ name: el.name, items: [{ q: el.q, b: el.b }] });
    } else {
        filteredArr[index].items.push({ q: el.q, b: el.b });
    }
});
console.log(filteredArr);//You will get your desired output

0
投票

您好,您可以使用带有查找功能的 for 循环。

我会尽力帮助你请检查下面的例子

let mainArr = [
    { name: 3, q: 10, b: 1 },
    { name: 5, q: 6, b: 2 },
    { name: 5, q: 7, b: 1 },
];

let setArr = [];

for (let arr of mainArr) {
    let checkValue = setArr.find((e) => e.name.toString() === arr.name.toString());

    if (!checkValue) {
        setArr.push({ name: arr.name, items: [{ q: arr.q, b: arr.b }] });
    } else {
        checkValue.items.push({ q: arr.q, b: arr.b });
    }
}

console.log(JSON.stringify(setArr, null, 2));

Result: [
    { name: 3, items: [{ q: 10, b: 1 }] },
    {
        name: 5,
        items: [
            { q: 6, b: 2 },
            { q: 7, b: 1 },
        ],
    },
];

希望对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.