将数组中的对象合并并推送到对象中的数组
- 最后,每
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
阵列
不知道你是否有一些限制,但这就是我该怎么做。
遍历所有对象并将它们放入对象中。该对象的关键将是名称。检查对象是否存在,如果它没有添加它并用[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的第一个对象,所以如果没有使用这些对象的其他地方,这很好......如果没有,你应该在减少功能复制和修改现有的对象,而不是。
谢谢。这很有帮助。 –
啊,我没有看到'号码'已经是一个数组...然后你必须遍历所有的数字,并检查它们是否已经在那里.. –
如果你只是想保持唯一的数字,你只需要检查数字是否已经英寸
这个例子首先创建一个新的对象,检查是否当它不是该名称已经存在,它会将它作为一个全新的参考(包括数组数组,因此您的原始数据源保持不变),并且如果它存在,它将循环遍历数组数组,以查看应该添加哪些数组。
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]));
随着号码列表的增长需要更多的循环播放数字时间。这不是一个大问题,因为一个人不可能有1000个数字,但是一旦你累积了所有数字,你就会更好地过滤数字1次。 –
@LoïcFaure-Lacroix对,对于目前的数据集来说,这是真的,但这并不是什么“大”,但我可以看到你的观点 – Icepickle
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);
哦。我刚才在想,只要减少就可以做到这一点。忘记计数部分 –