javascript - Förslag för att navigera i ett json-objektgraf
Jag letar efter alternativa sätt att parsa ett JSON-träd. Med följande exempel:
{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
}
}
om jag försöker komma åt grenar, såsom address.streetAddress eller address.city, då kan jag se två sätt att få det värdet:
1) JSON-sökväg med de ovan listade frågorna
2) Dela manuellt upp frågan i "grenar" (huvudgrensadress, undergrens gatadress) och kontrollera sedan objektens nycklar på det sättet.
Finns det några bättre sätt att göra detta på? Och med bättre menar jag effektivt, inte nödvändigtvis 'rent' i termer av kod.
Tillämpningen av nämnda kod skulle vara att använda detta inom en NGRX metareducer för att automatiskt spara objektet till localstorage, så det kommer potentiellt att utvärdera ett stort träd mycket ofta.
Tack.
Efter att ha testat olika metoder slutade jag med att välja _ug:s svar.
Data nedan, samt en sammanfattning av skriptet jag använde (utan data, som var känslig). Jag körde varje funktion 1 miljon gånger över 4 frågor.
Executing test: empty test
Average time for 1,000,000 executions: 6.181699991226196 milliseconds.
Executing test: split and reduce
Average time for 1,000,000 executions: 429.71359902620316 milliseconds.
Executing test: lodash
Average time for 1,000,000 executions: 1091.8809990286827 milliseconds.
Executing test: json path
Average time for 1,000,000 executions: 32114.680999994278 milliseconds.
Svar #1
Du kan använda lodash _.property-metoden för att göra detta: https://lodash.com/docs/4.17.15#property
const _ = require('lodash');
let obj = {
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
}
}
console.log(_.property('address.streetAddress')(obj));
// Or
console.log(_.propertyOf(obj)('address.streetAddress'));
Svar #2
Tillfälligtvis skrev jag precis något för detta, det fungerar inte för arrayer men är väldigt enkelt.
let obj = {
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
}
}
function jsonPath(path, obj) {
return path.split('.').reduce((o, p) => o[p], obj);
}
console.log(jsonPath('address.streetAddress', obj));
console.log(jsonPath('address.city', obj));Du kan också anpassa det för att köras med arrayer genom att ändra split för att hantera parenteser split(/[\[\.\]]+/)
Du kan också få det att returnera undefined istället för att kasta ett fel när ett sökvägsvärde inte hittas genom att ändra reduce till reduce((o, p) => o && o[p], obj)
Resultatet skulle vara:
let obj = {
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"addresses" : [{
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
}]
}
function jsonPath(path, obj) {
return path.split(/[\[\.\]]+/).reduce((o, p) => o && o[p], obj);
}
console.log(jsonPath('addresses[0].streetAddress', obj));
console.log(jsonPath('addresses[0].city', obj));
console.log(jsonPath('addresses[2].city', obj));