864 Stimmen

Wie erhält man unterschiedliche Werte aus einem Array von Objekten in JavaScript?

Angenommen, ich habe die folgenden Daten:

var array = 
    [
        {"name":"Joe", "age":17}, 
        {"name":"Bob", "age":17}, 
        {"name":"Carl", "age": 35}
    ]

Was ist der beste Weg, um in der Lage sein, ein Array aller unterschiedlichen Alter zu erhalten, so dass ich ein Ergebnis-Array von erhalten:

[17, 35]

Gibt es eine Möglichkeit, ich könnte alternativ die Daten oder bessere Methode strukturieren, so dass ich nicht durch jedes Array Überprüfung der Wert von "Alter" und überprüfen Sie gegen ein anderes Array für seine Existenz, und fügen Sie es, wenn nicht zu iterieren würde?

Wenn es eine Möglichkeit gäbe, einfach die verschiedenen Altersstufen herauszufinden, ohne zu iterieren...

Die derzeitige ineffiziente Methode würde ich gerne verbessern... Wenn es bedeutet, dass anstelle von "Array" ein Array von Objekten, sondern eine "Karte" von Objekten mit einigen eindeutigen Schlüssel (z. B. "1,2,3"), das wäre auch okay. Ich bin nur auf der Suche nach dem leistungsfähigsten Weg.

Das Folgende ist, wie ich es derzeit tun, aber für mich, Iteration scheint nur für die Effizienz crummy sein, obwohl es funktioniert ...

var distinct = []
for (var i = 0; i < array.length; i++)
   if (array[i].age not in distinct)
      distinct.push(array[i].age)

4voto

simo Punkte 14048

Ich habe dies gerade gefunden und dachte, es sei nützlich

_.map(_.indexBy(records, '_id'), function(obj){return obj})

Wiederum mit Unterstrich Wenn Sie also ein Objekt wie dieses haben

var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]

erhalten Sie nur die einzigartigen Objekte.

Was hier geschieht, ist, dass indexBy gibt eine Karte wie diese zurück

{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }

und nur weil es sich um eine Karte handelt, sind alle Schlüssel eindeutig.

Dann mappe ich diese Liste einfach auf ein Array zurück.

Falls Sie nur die eindeutigen Werte benötigen

_.map(_.indexBy(records, '_id'), function(obj,key){return key})

Beachten Sie, dass die key wird als String zurückgegeben. Wenn Sie stattdessen ganze Zahlen benötigen, sollten Sie

_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})

3voto

Craig Punkte 1991

Einfacher Einzeiler mit großartiger Leistung. 6% schneller als die ES6-Lösungen in meinem Tests .

var ages = array.map(function(o){return o.age}).filter(function(v,i,a) {
    return a.indexOf(v)===i
});

3voto

Yuanzhe Cui Punkte 477
const array = [{
    "name": "Joe",
    "age": 17
  },
  {
    "name": "Bob",
    "age": 17
  },
  {
    "name": "Carl",
    "age": 35
  }
]

const uniqueArrayByProperty = (array, callback) => {
  return array.reduce((prev, item) => {
    const v = callback(item);    
    if (!prev.includes(v)) prev.push(v)          
    return prev
  }, [])    
}

console.log(uniqueArrayByProperty(array, it => it.age));

3voto

bmaggi Punkte 2643

Wenn Sie wie ich eine "funktionalere" Lösung bevorzugen, ohne Kompromisse bei der Geschwindigkeit einzugehen, verwendet dieses Beispiel eine schnelle Wörterbuchsuche, die in eine reduzierte Schließung eingepackt ist.

var array = 
[
    {"name":"Joe", "age":17}, 
    {"name":"Bob", "age":17}, 
    {"name":"Carl", "age": 35}
]
var uniqueAges = array.reduce((p,c,i,a) => {
    if(!p[0][c.age]) {
        p[1].push(p[0][c.age] = c.age);
    }
    if(i<a.length-1) {
        return p
    } else {
        return p[1]
    }
}, [{},[]])

Nach diesem Test meine Lösung ist doppelt so schnell wie die vorgeschlagene Antwort

3voto

quillbreaker Punkte 6011

Wenn Sie Array.prototype.includes haben oder bereit sind Polyfill das funktioniert:

var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X