2016-12-06 111 views
0
  • 最后,每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阵列

+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)) 

请注意,我ediding的第一个对象,所以如果没有使用这些对象的其他地方,这很好......如果没有,你应该在减少功能复制和修改现有的对象,而不是。

+0

谢谢。这很有帮助。 –

+0

啊,我没有看到'号码'已经是一个数组...然后你必须遍历所有的数字,并检查它们是否已经在那里.. –

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]));

+0

随着号码列表的增长需要更多的循环播放数字时间。这不是一个大问题,因为一个人不可能有1000个数字,但是一旦你累积了所有数字,你就会更好地过滤数字1次。 –

+0

@LoïcFaure-Lacroix对,对于目前的数据集来说,这是真的,但这并不是什么“大”,但我可以看到你的观点 – Icepickle

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);