[JS] Nested array of objects

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 21:54
Hallo,

Ik ben geen programmeur maar ben wel op ontdekking... :-)

Ik heb volgende Array of Objects:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let db = [
    {
        who: 'jan',
        family: []
    },
    {
        who: 'piet',
        family: []
    },
    {
        who: 'pol',
        family: [{gender: "male" , name: "dirk"}, {gender: "female" , name: "iris"}]
    }
]


Ik zou graag deze array of objects filteren op naam en hun familieleden zien verschijnen op het scherm. Ik filter bijvoorbeeld op de naam "pol"
JavaScript:
1
2
3
4
5
6
let found = db.find(e => e.who === "pol")
if (found !== undefined) {
    console.log(found.family)
} else { 
    console.log("Didn't found the name")
}


Het resultaat is:
JavaScript:
1
2
3
4
[
  { gender: 'male', name: 'dirk' },
  { gender: 'female', name: 'iris' }
]


Een volgende stap die ik graag zou willen bekomen is filteren op "pol" EN enkel de "female" personen tonen. Het resultaat dat ik dus verwacht te zien is: "iris".

Hoe kan ik dit bekomen?

Alvast bedankt!

Beste antwoord (via argon007 op 17-09-2021 20:35)


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je hebt in principe alle onderdelen al. Je weet hoe find werkt, dat moet je alleen nog toepassen op de gevonden "found.family" :)

Daarnaast wil je waarschijnlijk meer dan 1 resultaat kunnen hebben, dan kun je kijken naar de Filter functie. Die doet ongeveer hetzelfde als find, maar geeft weer een array terug

[ Voor 52% gewijzigd door Woy op 17-09-2021 14:42 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Alle reacties


Acties:
  • +1 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Opnieuw een `find` doen op je `found` variabele?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je hebt in principe alle onderdelen al. Je weet hoe find werkt, dat moet je alleen nog toepassen op de gevonden "found.family" :)

Daarnaast wil je waarschijnlijk meer dan 1 resultaat kunnen hebben, dan kun je kijken naar de Filter functie. Die doet ongeveer hetzelfde als find, maar geeft weer een array terug

[ Voor 52% gewijzigd door Woy op 17-09-2021 14:42 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 21:54
Haha, cool! :-)

JavaScript:
1
2
3
4
5
6
7
let found = db.find(e => e.who === "pol")
if (found !== undefined) {
    let filter = found.family.find(e => e.gender === "male")
    console.log(filter.name)
} else { 
    console.log("Didn't found the name")
}

geeft mij inderdaad: "dirk"

Is er een mogelijkheid om dit in 1 IF / commando te krijgen zodat ik onmiddellijk kan filteren op "pol" EN "male"? Of is dit onmogelijk?

Acties:
  • +1 Henk 'm!

  • ocwil
  • Registratie: Mei 2007
  • Laatst online: 25-09 16:29
Zoiets zou je het kunnen filteren in 1 functie, heb het alleen even uitgezocht omdat ik het zelf ook niet wist :P

JavaScript:
1
2
3
4
5
6
7
db.filter(function(obj) {
  if(obj.who === "pol"){
    found = obj.family.filter(e => e.gender === "male");
  }
});

console.log(found);


EDIT *disclaimer*: Mijn kennis van Js is niet groot dus er kunnen best wat problemen nog zijn met deze code als er bijvoorbeeld meerdere "pol" items in de data zitten en hoe de performance is bij grotere arrays bijvoorbeeld.

[ Voor 28% gewijzigd door ocwil op 17-09-2021 15:34 ]

~ Portal 2 maps: linkje ~ LoL (EUW): Ocwil ~


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
argon007 schreef op vrijdag 17 september 2021 @ 14:53:
Is er een mogelijkheid om dit in 1 IF / commando te krijgen zodat ik onmiddellijk kan filteren op "pol" EN "male"?
Je kan het op 1 regel proppen met twee relatief nieuwe operators: de ?. en ??

JavaScript:
1
console.log(db.find(e => e.who === "pol")?.family.find(e => e.gender === "male")?.name ?? "Didn't find the name");


Maar het is geen probleem als je meerdere regels gebruikt. Soms is dat beter leesbaar en verdient het de voorkeur boven 1 lange ingewikkelde regel.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Dit wil je echt niet in 1 regel doen :) Het zijn 2 losse zoekacties. Losse regels houdt het logischer en leesbaarder

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Op zich kun je het prima in een enkel statement doen ( Ik zou het alsnog over meerdere regels doen voor leesbaarheid ).

JavaScript:
1
2
let persons = db.filter( rec => rec.who == "name" )
                .map( rec => rec.family.filter( person => person.gender == "male" ));


Met de eerste filter filter je de records, daarna doe je een map om een projectie te maken naar het resultaat dat je wil hebben. Die projectie is dan een gefilterd resultaat van de family property.

Projectie van array elementen met de map function.

[ Voor 13% gewijzigd door Woy op 20-09-2021 15:29 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Dat is chaining en dat is prima :)

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • argon007
  • Registratie: April 2011
  • Laatst online: 21:54
Bedankt aan allen!
Pagina: 1