我正在寻找一种更有效的方法来连接基于2个字段中重复的数组成员,理想情况下不使用循环内的循环。
数组已按name
和email
升序排序 - 如果两行具有相同的name
和email
,我想“合并“这些行合并为一行,第一行的drink
字段变为drink_1
,第二行的drink
字段变为drink_2
。
输入:
[
{name: 'bob', email: 'bob@bob.com', drink: 'beer'},
{name: 'bobs_alias', email: 'bob@bob.com', drink: 'beer'},
{name: 'john', email: 'john@john.com', drink: 'beer'},
{name: 'john', email: 'john@john.com', drink: 'cider'},
{name: 'mike', email: 'mike@mike.com', drink: 'wine'},
{name: 'mike', email: 'mike@mike.com', drink: 'water'}
]
期望的输出:
[
{ name: 'bob', email: 'bob@bob.com', drink: 'beer'},
{ name: 'bobs_alias', email: 'bob@bob.com', drink: 'beer'},
{ name: 'john', email: 'john@john.com', drink_1: 'beer', drink_2: 'cider'},
{ name: 'mike', email: 'mike@mike.com', drink_1: 'wine', drink_2: 'water'}
]
答案 0 :(得分:1)
使用Array.prototype.reduce
和hash table
来获取所需的结果 - 因为它使用哈希表,即使没有已排序的输入,此提案也可以。
见下面的演示:
var array=[{name:'bob',email:'bob@bob.com',drink:'beer'},{name:'bobs_alias',email:'bob@bob.com',drink:'beer'},{name:'john',email:'john@john.com',drink:'beer'},{name:'john',email:'john@john.com',drink:'cider'},{name:'mike',email:'mike@mike.com',drink:'wine'},{name:'mike',email:'mike@mike.com',drink:'water'}];
var result = array.reduce(function(hash) {
return function(p, c) {
let key = `${c.name}_${c.email}`;
if (hash[key]) {
if (hash[key].drink) {
hash[key]['drink_' + ++hash[key + '_num']] = hash[key].drink;
delete hash[key].drink;
}
hash[key]['drink_' + ++hash[key + '_num']] = c.drink;
} else {
hash[key] = c;
hash[key + '_num'] = 0;
p.push(hash[key]);
}
return p;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper {top: 0;max-height: 100%!important;}
答案 1 :(得分:0)
您可以尝试这样的事情:
var d = [{name: "bob", email: "bob@bob.com", drink: "beer"},
{name: "bobs_alias", email: "bob@bob.com", drink: "beer"},
{name: "john", email: "john@john.com", drink: "beer"},
{name: "john", email: "john@john.com", drink: "cider"},
{name: "john", email: "john@john.com", drink: "wine"},
{name: "mike", email: "mike@mike.com", drink: "wine"},
{name: "mike", email: "mike@mike.com", drink: "water"}];
var r = [];
d.sort(function(a, b) {
return a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
}).reduce(function(p, c) {
if (p.name === c.name && p.email === c.email) {
var index = Object.keys(p).reduce(function(i, k) {
var str = k.replace('drink_', '');
if (!isNaN(str)) i = Math.max(+str, i) + 1;
return i;
}, 1);
if (p.drink) {
p['drink_' + index++] = p.drink;
}
p['drink_' + index] = c.drink;
delete p.drink;
return p;
} else {
r.push(c)
return c;
}
})
console.log(r)
&#13;
答案 2 :(得分:0)
使用map()
和filter()
的组合,我们可以完成此任务。
试试这个:
console.clear();
var ps = [
{name: 'bob', email: 'bob@bob.com', drink: 'beer'},
{name: 'bobs_alias', email: 'bob@bob.com', drink: 'beer'},
{name: 'john', email: 'john@john.com', drink: 'beer'},
{name: 'john', email: 'john@john.com', drink: 'cider'},
{name: 'mike', email: 'mike@mike.com', drink: 'wine'},
{name: 'mike', email: 'mike@mike.com', drink: 'water'}
]
var temp = [], n = 1, obj = {};
var x = ps.map(function(el, i) {
var t = el.name + el.email;
if(t !== temp[0]) {
temp[0] = t;
n = 1;
obj = null;
return el;
} else {
obj = ps[i-1];
obj['drink_' + n] = obj['drink'];
delete obj['drink'];
obj['drink_' + (n + 1)] = el['drink'];
n++;
return null;
}
})
//filter null value from array element
var y = x.filter(function(el,i){
return el !== null;
})
//print in console
y.forEach(function(e) {console.log(e);})
答案 3 :(得分:0)
通常情况下,我是使用某种散列的粉丝,但由于数组已经排序,因此可以简单地向前看每个条目:
var arr=[{name:'bob',email:'bob@bob.com',drink:'beer'},{name:'bobs_alias',email:'bob@bob.com',drink:'beer'},{name:'john',email:'john@john.com',drink:'beer'},{name:'john',email:'john@john.com',drink:'cider'},{name:'mike',email:'mike@mike.com',drink:'wine'},{name:'mike',email:'mike@mike.com',drink:'water'}];
for(let i=0; i < arr.length; i++)
for(let j =i +1, ind = 2; j< arr.length && arr[i].name === arr[j].name && arr[i].email === arr[j].email; j++){
if(arr[i].drink){
arr[i].drink_1 = arr[i].drink;
delete arr[i].drink;
}
arr[i]['drink_' + ind++] = arr.splice(j--,1)[0].drink;
}
console.log(arr);
&#13;