使用相同的键合并数组中的javascript对象

sis*_*nts 29 javascript arrays

什么是重组的最佳方式array进入output?我需要将所有值键(无论是否为数组)合并到共享相同名称键的对象中.这里有类似的东西,但这并没有回答我的问题,因为我也有数组.

var array = [
    {
        name: "foo1",
        value: "val1"
    }, {
        name: "foo1",
        value: [
            "val2",
            "val3"
        ]
    }, {
        name: "foo2",
        value: "val4"
    }
];

var output = [
    {
        name: "foo1",
        value: [
            "val1",
            "val2",
            "val3"
        ]
    }, {
        name: "foo2",
        value: [
            "val4"
        ]
    }
];
Run Code Online (Sandbox Code Playgroud)

是的,我可以for在两者之间编写无限循环和几个数组,但是有一个简单的(r)快捷方式吗?谢谢!

Ben*_*enG 35

这是一个选项: -

var array = [{
  name: "foo1",
  value: "val1"
}, {
  name: "foo1",
  value: ["val2", "val3"]
}, {
  name: "foo2",
  value: "val4"
}];

var output = [];

array.forEach(function(item) {
  var existing = output.filter(function(v, i) {
    return v.name == item.name;
  });
  if (existing.length) {
    var existingIndex = output.indexOf(existing[0]);
    output[existingIndex].value = output[existingIndex].value.concat(item.value);
  } else {
    if (typeof item.value == 'string')
      item.value = [item.value];
    output.push(item);
  }
});

console.dir(output);
Run Code Online (Sandbox Code Playgroud)

  • 我的`key`和`value`名称不同.我感到很困惑,因为输入对象中的`value`名称是`value`,而你在`forEach`循环中的参数名也被命名为value.请把我的困惑弄清楚.谢谢. (3认同)

Ngu*_*ong 15

2021版

var arrays = [{ name: "foo1",value: "val1" }, {name: "foo1", value: ["val2", "val3"] }, {name: "foo2",value: "val4"}];

const result = arrays.reduce((acc, {name, value}) => {
  acc[name] ??= {name: name, value: []};
  if(Array.isArray(value)) // if it's array type then concat 
    acc[name].value = acc[name].value.concat(value);
  else
    acc[name].value.push(value);
  
  return acc;
}, {});

console.log(Object.values(result));
Run Code Online (Sandbox Code Playgroud)

  • @MekelIlyasa,您好,这意味着“逻辑无效赋值”。它等于检查条件 `if(!acc[name]) acc[name] = {name: name, value: []}` (3认同)
  • 嗨,这里是新手。`??=` 是什么意思? (2认同)

Hun*_*yan 11

以下是实现该目标的另一种方法:

var array = [{
  name: "foo1",
  value: "val1"
}, {
  name: "foo1",
  value: [
    "val2",
    "val3"
  ]
}, {
  name: "foo2",
  value: "val4"
}];

var output = array.reduce(function(o, cur) {

  // Get the index of the key-value pair.
  var occurs = o.reduce(function(n, item, i) {
    return (item.name === cur.name) ? i : n;
  }, -1);

  // If the name is found,
  if (occurs >= 0) {

    // append the current value to its list of values.
    o[occurs].value = o[occurs].value.concat(cur.value);

    // Otherwise,
  } else {

    // add the current item to o (but make sure the value is an array).
    var obj = {
      name: cur.name,
      value: [cur.value]
    };
    o = o.concat([obj]);
  }

  return o;
}, []);

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


tri*_*cot 9

这是使用 ES6 Map 的版本:

const arrays = [{ name: "foo1",value: "val1" }, {name: "foo1", value: ["val2", "val3"] }, {name: "foo2",value: "val4"}];

const map = new Map(arrays.map(({name, value}) => [name, { name, value: [] }])); 
for (let {name, value} of arrays) map.get(name).value.push(...[value].flat());
console.log([...map.values()]);
Run Code Online (Sandbox Code Playgroud)


pao*_*eno 8

使用lodash

var array = [{name:"foo1",value:"val1"},{name:"foo1",value:["val2","val3"]},{name:"foo2",value:"val4"}];

function mergeNames (arr) {
    return _.chain(arr).groupBy('name').mapValues(function (v) {
        return _.chain(v).pluck('value').flattenDeep();
    }).value();
}

console.log(mergeNames(array));
Run Code Online (Sandbox Code Playgroud)

  • 简化版和 pluck 现在应该是 map :`const mergeNames = arr => _.chain(arr).groupBy('name').mapValues(v => _.chain(v).map('value')。 flattenDeep()).value(); console.log(mergeNames(array));` (2认同)