2016-12-06 1 views
0
  • Am Ende sollte nur ein Objekt pro name sein.
  • Wenn es mehr Objekte mit demselben Namen gibt es so machen, dass die number Array für jedes Objekt in das für diesen Namen eines Objekt kombiniert bekommen
  • Die ein Objekt mit dem gleichen Namen keine doppelten Elemente in den number haben sollte Array.
  • Die Elemente im Zahlenfeld sollten in derselben Reihenfolge angezeigt werden, in der sie im ursprünglichen Array erscheinen.kombinieren Objekte in einem Array und drücken Sie auf ein Array im Objekt

    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"]} 
    
    ] 
    

Ich war in der Lage, um herauszufinden, wie oft ein Objekt mit dem gleichen Namen

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) 

aufgetreten ist, aber dann wurde es kompliziert, weil ich nicht wusste, wie die Duplikate zu entfernen und Lassen Sie eins und kombinieren Sie die number Array

+0

Oh. Ich dachte gerade, ich könnte das mit nur reduzieren. und vergiss den zählenden Teil –

Antwort

0

Nicht sicher, ob Sie einige Einschränkungen haben, aber das ist, wie ich es tun würde.

Schleife über alle deine Objekte und lege sie in ein Objekt. Der Schlüssel des Objekts ist der Name. Überprüfen Sie, ob das Objekt existiert, wenn es nicht hinzugefügt wird und ersetzen Sie die number durch [number], wenn das Objekt bereits existiert, fügen Sie einfach die Nummer mit push hinzu.

Sobald Sie über alle Ihre Objekte geloopt haben, konvertieren Sie dieses Objekt in eine Liste und das war's.

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

Bitte beachte, dass ich das erste Objekt bin ediding so, wenn es nicht für diese Objekte anderswo verwendet wird, das ist in Ordnung ... wenn nicht, Sie in der Funktion reduzieren, anstatt zu modifizieren und bestehende Objekt kopieren sollen.

+0

Danke. Dies ist hilfreich. –

+0

Ah Ich habe nicht gesehen, 'Nummer' ist schon ein Array ... dann müssen Sie alle Nummern durchlaufen und überprüfen, ob sie schon da sind. –

0

Wenn Sie nur die eindeutigen Nummern behalten wollen, müssen Sie nur überprüfen, ob die Zahlen sind bereits in.

In diesem Beispiel wird ein neues Objekt zunächst überprüft, ob der Name bereits vorhanden ist, wenn es nicht der Fall ist existieren, fügt es als eine völlig neue Referenz hinzu (einschließlich des Zahlen-Arrays, so dass Ihre ursprüngliche Quelle gleich bleibt) und wenn es existiert, wird es durch das Zahlen-Array laufen, um zu sehen, welche noch hinzugefügt werden sollten.

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

Immer wieder die Nummern zu durchlaufen, wenn die Nummernliste wächst, wird mehr kosten Zeit.Es ist keine große Sache, weil es unwahrscheinlich ist, dass eine Person 1000 von Zahlen hat, aber Sie würden besser sein, die Zahlen einmal zu filtern, sobald Sie alle Zahlen angesammelt haben. –

+0

@ LoïcFaure-Lacroix Ja, das stimmt, aber für den aktuellen Datensatz ist das nicht etwas "Großes", obwohl ich Ihren Standpunkt sehen kann – Icepickle

0

Weitere (ES6) Version für den Mix: eine mit Map und Sets

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

Verwandte Themen