组合数组中的对象并推送到对象中的数组

时间:2016-12-06 11:28:31

标签: javascript arrays object

  • 最后每个name应该只有一个对象。
  • 如果有的话 具有相同名称的多个对象使得每个对象的number数组合并到该名称的一个对象中
  • 具有相同名称的一个对象不应在number数组中包含重复的元素。
  • 数字数组中的元素应与原始数组中显示的顺序相同。

    var arrT = [
        {name : "x.com", number :["123-456-789"]}, {name : "x.com", number :["452-123-789"]},{name : "y.com", number :["123-456-000"]}, 
        {name : "x.com", number :["123-456-789"]}, {name : "y.com", number :["123-456-000"]}, {name : "b.com", number :["178-456-000"]}
    
    
        ]
    
    output should be:[
    {name : "x.com", number : ["123-456-789", "452-123-789"]}, //notice: 123-456-789 didn't appear twice
    {name : "y.com", number : ["123-456-000"]},
    {name : "b.com", number :["178-456-000"]}
    
    ]
    

我能够找出具有相同名称的对象发生了多少次

var occurrences = nArr.reduce(function(acc, curr,i){
    if(typeof acc[curr.name] == "undefined"){
        acc[curr.name] = 1;
    }else{
        acc[curr.name] += 1
    }
    return acc;
}, {});
console.log(occurrences)

var moreThanOne = [];
for(var key in occurrences){
    if(occurrences[key] > 1){
        moreThanOne.push(key);
    }
}
console.log("moreThanOne", moreThanOne)

然后它变得复杂,因为我不知道如何删除重复项并留下一个并组合number数组

3 个答案:

答案 0 :(得分:0)

不确定你是否有一些约束,但这就是我的做法。

遍历所有对象并将它们放入对象中。对象的关键是名称。检查对象是否存在,如果它没有添加,并将[number]替换为push,如果该对象已存在,只需添加function groupByName(accum, obj) { if (accum[obj.name]) { // add all numbers! don't check for uniqueness yet accum[obj.name].number = accum[obj.name].concat(obj.number) } else { accum[obj.name] = obj obj.number = [obj.number] } return accum } function removeDuplicates(accum, value) { if (accum.length == 0 && accum[accum.length - 1] != value) { accum.push(value) } return accum } function toList(context) { return function (key) { var obj = context[key] obj.number.sort() obj.number = obj.number.reduce(removeDuplicates, []) return obj } } objs = arrT.reduce(groupByName, {}) output = Object.keys(objs).map(toList(objs)) 的数字。

将所有对象循环后,将该对象转换为列表即可。

a = [1,2,3,1,4,5]

请注意,我正在编辑第一个对象,所以如果其他地方没有使用这些对象,那很好......如果没有,你应该复制reduce函数而不是修改现有对象。

答案 1 :(得分:0)

如果您只想保留唯一的数字,您只需检查数字是否已经存在。

此示例首先创建一个新对象,检查该名称是否已存在,如果该名称不存在,则将其添加为全新引用(包括数字数组,因此原始源保持不变),如果它确实存在,它将遍历数字数组以查看应该添加哪些数据。

var arrT = [{
  name: "x.com",
  number: ["123-456-789"]
}, {
  name: "x.com",
  number: ["452-123-789"]
}, {
  name: "y.com",
  number: ["123-456-000"]
}, {
  name: "x.com",
  number: ["123-456-789"]
}, {
  name: "y.com",
  number: ["123-456-000"]
}, {
  name: "b.com",
  number: ["178-456-000"]
}];

var reduced = arrT.reduce((nextState, item) => {
  var key = item.name,
    o;
  if (!(o = nextState[key])) {
    // clones the item, and the number array
    nextState[key] = { ...item, number: [...item.number] };
  } else {
    item.number.forEach(number => o.number.indexOf(number) === -1 && o.number.push(number));
  }
  return nextState;
}, {});

console.log(arrT);
console.log(Object.keys(reduced).map(key => reduced[key]));

答案 2 :(得分:0)

混音的另一个(ES6)版本:MapSets



let  arrT = [{name : "x.com", number :["123-456-789"]}, {name : "x.com", number :["452-123-789"]},{name : "y.com", number :["123-456-000"]}, {name : "x.com", number :["123-456-789"]}, {name : "y.com", number :["123-456-000"]}, {name : "b.com", number :["178-456-000"]}    ];
    
 let  res = [...arrT.reduce((m,o) => {
    let set = m.get(o.name);
    if(!set) m.set(o.name, set = new Set());
    for(let n of o.number) set.add(n);
    return m;
 }, new Map())]
 .map(([na,[...nrs]])=>({name:na,number:nrs}));
 
 console.log(res);