2016-07-09 17 views
1

Sagt sich, ich habe ein tiefes Objekt wie diesejavascript/lodash: wie ein Unterbaumobjekt

cont obj = { 
    a0: { 
    b0: { 
     c0: 0, 
     c1: 1 
     }, 
     b1: { 
     c2: 2 
     } 
    } 
} 

und ich möchte in einem einzigen Verfahren eine rekursive tief get in einem Objekt dank tun, um einen Unter abrufen Baum davon von api mit dieser Art wollen wir es retrieveDeep 'Name:

const subObj = retrieveDeep(
obj, 
{ 
    a0: { 
    b0: { 
     c0: null 
    }, 
    b1: { 
     c2: null 
    } 
    } 
} 
) 
// should return 
// { 
// a0: { 
//  b0: { 
//  c0: 0 
//  }, 
//  b1: { 
//  c2: 2 
//  } 
//  } 
// } 

ich eigentlich weiß, dass ich mit nicht so viel Schwierigkeiten, die von Grund auf neu implementieren könnte, aber wenn es bereits eine lodash (oder sogar sieht aus wie ein bisschen die graphQL api Form!) Funktion, ich würde mich freuen, es zu wissen tx

+0

Ich habe hier nur den Wert 'null' als Targeting-Platzhalter verwendet (dies ist eine willkürliche Wahl), der durch den wahren Wert ersetzt wird, der dem entsprechenden Schlüssel entspricht ... Also wird er durch ein Objekt, eine Zahl, ersetzt. ein String ... hängt nur vom entsprechenden Wert im Quellobjekt ab. –

+1

und was hast du probiert? –

+0

Nichts für noch, eigentlich könnte ich die rekursive Funktion in 10 Minuten schreiben, aber ich wollte nur sicher sein, dass es keine Synchronisation über diese Frage gibt und schon eine bestimmte gemeinsame Funktion in der Community :). –

Antwort

1

Iterieren Sie einfach die Eigenschaften des Musters und führen Sie rekursive Aufrufe für Objekte durch. Zuweisen primitiver Werte

function retrieveDeep(object, pattern) { 
 
    function iter(o, p, r) { 
 
     Object.keys(p).forEach(function (k) { 
 
      if (k in o) { 
 
       if (typeof o[k] === 'object' && o[k] !== null) { 
 
        r[k] = {}; 
 
        iter(o[k], p[k], r[k]); 
 
        return; 
 
       } 
 
       r[k] = o[k]; 
 
      } 
 
     }); 
 
    } 
 
    
 
    var result = {}; 
 
    iter(object, pattern, result); 
 
    return result; 
 
} 
 

 
var obj = { a0: { b0: { c0: 0, c1: 1 }, b1: { c2: 2 } } }, 
 
    subObj = retrieveDeep(obj, { a0: { b0: { c0: null }, b1: { c2: null } } }); 
 

 
console.log(subObj);

+1

Coole TX! Und ich habe gerade die Bedingung 'if (typeof o [k] ===' object ') 'durch' if (p [k]! == null) ersetzt, um tatsächlich auch die möglichen verschachtelten Objekte, Arrays, zu erhalten will auch. –

1

Mit lodash 1+, gibt es einen kürzesten Weg unter Verwendung _.at (Objekt, [Pfade]):

let exist = { 
 
    a:{ 
 
    b: {c: 3} 
 
    }, 
 
    ZZ: 2 
 
}; 
 
    
 
let resExist = _.at(exist, 'a.b.c').pop() // => 3 
 

 
let notExit = { a : 1 } 
 
    
 
let resNoExist = _.at(notExit, 'a.b.c').pop() // undefined 
 
    
 
console.log('resExist', resExist) 
 
console.log('resNoExist', resNoExist)
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

siehe documention