Ich habe eine ähnliche Struktur (nur Testdaten, daher sind Tippfehler irrelevant):
"People" : [
{
"name": "Bob",
"animals" : [{
"name" : "Scott",
"type" : "Cat"
},
{
"name" : "Eva",
"type" : "Cat"
}
{
"name" : "Sven",
"type" : "Dog"
}]
},
{
"name": "Bob",
"animals" : [{
"name" : "Chris",
"type" : "Dog"
},
{
"name" : "Greg",
"type" : "Cat"
},
{
"name" : "Ior",
"type" : "Horse"
}]
}
]
Grundsätzlich möchte ich alle einzigartigen Tierarten aus dieser Sammlung erhalten. Mein Problem ist die Zuordnung zu zwei Arrays (People : [], Animals : []
). Die Frage:
Wie ordne ich alle "Typ" -Attribute zu, um eine neue eindeutige Sammlung zu erhalten? mögen:
["Cat", "Dog", "Horse"]
Wird aktualisiert, wenn ich ein Beispiel mit C # LINQ fertigstelle.
5 Antworten
let _animals = {}
People.forEach(person => {
person.animals.forEach(animal => {
_animals[animal.name] = true
})
})
let result = Object.keys(_animals)
Verbessert mit mehr es6:
let _animals = {}
People.forEach(({animals}) =>
animals.forEach(({name}) =>
_animals[name] = true
)
)
let result = Object.keys(animals)
Verwenden Sie reduce
, map
, concat
und schließlich Set
bis Array
, wie unten gezeigt
var output = [...new Set( arr.reduce( (a,c) => a.concat( c.animals.map( s => s.type )) , []))]
Erklärung:
- Verwenden Sie
reduce
, um das Array (people
) zu iterieren und alle Werte für den Tiertyp abzurufen - Verwenden Sie
map
, um Tiere zu iterieren und ihre Typen zurückzugeben, und verketten Sie das Ergebnis vonmap
mit dem Akkumulatora
- Verwenden Sie
Set
, um Duplikate zu entfernen. - Verwenden Sie den Spread-Operator
...
, um ihn wieder inArray
zu konvertieren.
Demo
var arr = [{
"name": "Bob",
"animals": [{
"name": "Scott",
"type": "Cat"
},
{
"name": "Eva",
"type": "Cat"
},
{
"name": "Sven",
"type": "Dog"
}
]
},
{
"name": "Bob",
"animals": [{
"name": "Chris",
"type": "Dog"
},
{
"name": "Greg",
"type": "Cat"
},
{
"name": "Ior",
"type": "Horse"
}
]
}
];
var output = [...new Set(arr.reduce((a, c) => a.concat(c.animals.map(s => s.type)), []))];
console.log(output);
ES6
Sie können reduce()
, new Set([])
und die spread operator
an Holen Sie sich das gewünschte Ergebnis.
DEMO
const arr = [{
"name": "Bob",
"animals": [{
"name": "Scott",
"type": "Cat"
}, {
"name": "Eva",
"type": "Cat"
}, {
"name": "Sven",
"type": "Dog"
}]
}, {
"name": "Bob",
"animals": [{
"name": "Chris",
"type": "Dog"
}, {
"name": "Greg",
"type": "Cat"
}, {
"name": "Ior",
"type": "Horse"
}]
}];
let result = arr.reduce((r, {animals}) =>[...r,...animals.map(({type})=>type)], []);
console.log([ ...new Set(result)]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Siehe Set
und < a href = "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach" rel = "nofollow noreferrer"> Array.prototype.forEach()
für weitere Informationen Infos zu animalsFrom()
.
Siehe Array.prototype.map()
und Flattening Arrays
für weitere Informationen zur letzteren Methode (listAnimals()
).
// Input.
const input = {"people": [{"name": "Bob","animals": [{"name": "Scott","type": "Cat"},{"name" : "Eva","type": "Cat"},{"name" : "Sven","type": "Dog"}]},{"name": "Bob","animals": [{"name" : "Chris","type" : "Dog"},{"name": "Greg","type": "Cat"},{"name": "Ior","type": "Horse"}]}]}
// Animals From.
const animalsFrom = ({people}) => {
const animals = new Set()
people.forEach(person => {
person.animals.forEach(animal => animals.add(animal.type))
})
return [...animals.values()]
}
// List Animals (Advanced).
const listAnimals = ({people}) => [...new Set([].concat.apply([], people.map(({animals}) => animals.map(({type}) => type))))]
// Proof.
console.log('Animals From', animalsFrom(input))
console.log('List Animals', listAnimals(input))
var unique = {}; // Create an associative array
for (j = 0; j < People.length; j++) { // Iterate through Parents
for(i = 0; i < People[j].animals.length; i++) { // Iterate through animals
var node = unique[People[j].animals[i].type] = unique[People[j].animals[i].type] || {};
// Here unique is built. If there is no entry with the current type as the id, a new entry in unique will be added.
}
}