2016-11-25 64 views
2

我正在尋找一種更有效的方式來連接基於2個字段中的重複項的數組成員,理想情況下不需要在循環內部使用循環。基於部分重複連接行

的陣列已經被nameemail升序 - 如果兩行具有相同的nameemail,我想「合併」這些行連成一排與drink場從第一行成爲drink_1第二行的drink字段變成drink_2

輸入

[ 
    {name: 'bob', email: '[email protected]', drink: 'beer'}, 
    {name: 'bobs_alias', email: '[email protected]', drink: 'beer'}, 
    {name: 'john', email: '[email protected]', drink: 'beer'}, 
    {name: 'john', email: '[email protected]', drink: 'cider'}, 
    {name: 'mike', email: '[email protected]', drink: 'wine'}, 
    {name: 'mike', email: '[email protected]', drink: 'water'} 
] 

所需的輸出

[ 
    { name: 'bob', email: '[email protected]', drink: 'beer'}, 
    { name: 'bobs_alias', email: '[email protected]', drink: 'beer'}, 
    { name: 'john', email: '[email protected]', drink_1: 'beer', drink_2: 'cider'}, 
    { name: 'mike', email: '[email protected]', drink_1: 'wine', drink_2: 'water'} 
] 
+0

你的數據結構不理想。如果你在一個數組中收集了多個選擇,比如'drinks:[「beer」,「cider」]',那麼最好 – Redu

回答

0

你可以嘗試這樣的事情:

var d = [{name: "bob", email: "[email protected]", drink: "beer"}, 
 
{name: "bobs_alias", email: "[email protected]", drink: "beer"}, 
 
{name: "john", email: "[email protected]", drink: "beer"}, 
 
{name: "john", email: "[email protected]", drink: "cider"}, 
 
{name: "john", email: "[email protected]", drink: "wine"}, 
 
{name: "mike", email: "[email protected]", drink: "wine"}, 
 
{name: "mike", email: "[email protected]", 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)

1

使用Array.prototype.reducehash table以獲得所需的結果 - 因爲它使用散列表,因此即使沒有排序的輸入,該提議也可以運行

見下面的演示:

var array=[{name:'bob',email:'[email protected]',drink:'beer'},{name:'bobs_alias',email:'[email protected]',drink:'beer'},{name:'john',email:'[email protected]',drink:'beer'},{name:'john',email:'[email protected]',drink:'cider'},{name:'mike',email:'[email protected]',drink:'wine'},{name:'mike',email:'[email protected]',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;}

0

使用map()filter()我們可以實現這個任務的組合。 試試這個:

console.clear(); 
 
var ps = [ 
 
    {name: 'bob', email: '[email protected]', drink: 'beer'}, 
 
    {name: 'bobs_alias', email: '[email protected]', drink: 'beer'}, 
 
    {name: 'john', email: '[email protected]', drink: 'beer'}, 
 
    {name: 'john', email: '[email protected]', drink: 'cider'}, 
 
    {name: 'mike', email: '[email protected]', drink: 'wine'}, 
 
    {name: 'mike', email: '[email protected]', 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);})

0

通常情況下,我使用某種散列的粉絲,但是因爲數組已經排序,它可以簡單地向前看,每個條目:

var arr=[{name:'bob',email:'[email protected]',drink:'beer'},{name:'bobs_alias',email:'[email protected]',drink:'beer'},{name:'john',email:'[email protected]',drink:'beer'},{name:'john',email:'[email protected]',drink:'cider'},{name:'mike',email:'[email protected]',drink:'wine'},{name:'mike',email:'[email protected]',drink:'water'}]; 
 

 

 
for(let i=0; i < arr.length; i++) 
 
\t for(let j =i +1, ind = 2; j< arr.length && arr[i].name === arr[j].name && arr[i].email === arr[j].email; j++){ \t 
 
    \t if(arr[i].drink){ 
 
     \t arr[i].drink_1 = arr[i].drink; 
 
      delete arr[i].drink; 
 
     } 
 
    \t arr[i]['drink_' + ind++] = arr.splice(j--,1)[0].drink; 
 
    } 
 
    
 
console.log(arr);