2016-04-26 8 views
2

Gibt es eine elegantere Art, diese Codezeile zu schreiben?Mapping Array von Objekten und nur einmalig

_.chain(_.uniqBy(someArray,"someProperty.name")).map("someProperty").value(); 

es scheint, wie ich es an die Kette der Lage sein sollte, anstatt die lodash der Verschachtelung innerhalb des .chain Anruf .uniqBy zu nennen.

Ich würde erwarten, dass das Folgende funktioniert, aber es wird nicht.

_.chain(someArray).map("someProperty").value().uniqBy("name"); 

Der Eingang ist:

someArray = [ 
    { 
     aProp: '1', 
     anotherProp: '2', 
     thirdProp: '3', 
     someProperty: { 
      id: 1, 
      name: "john" 
     } 
    }, 
    { 
     aProp: '3', 
     anotherProp: '4', 
     thirdProp: '5', 
     someProperty: { 
      id: 1, 
      name: "john" 
     } 
    }, 
    { 
     aProp: '2', 
     anotherProp: 'f', 
     thirdProp: '6', 
     someProperty: { 
      id: 2, 
      name: "tom" 
     } 
    }, 
    { 
     aProp: 't', 
     anotherProp: 'g', 
     thirdProp: 'f', 
     someProperty: { 
      id: 3, 
      name: "yacob" 
     } 
    }, 
]; 

Die Ausgabe sollte:

[{id:1, name:"john"},{id:2, name:"tom"},{id:3, name:"yacob"}] 

Antwort

2

Eigentlich sind Sie auf dem richtigen Weg:

_.chain(data).map('someProperty').uniqBy('id').value() 
+2

Sie müssen auch nicht haben "Kette" Sie können tun: '_ (Daten) .map ('someProperty'). UniqBy ('id'). Value()' – Mike

+0

In In welcher Situation würdest du die Kette benutzen müssen? –

+1

'_ (data)' ist eine _implicit_ chain, daher sollten wir 'value' nicht aufrufen, wenn die letzte Methode ein einzelnes Objekt zurückgibt:' _ (data) .map ('someProperty'). UniqBy ('id'). Get (0) '. Wenn dieses Verhalten unerwünscht ist oder wir die Unterstrichschnittstelle anpassen möchten, könnten wir eine _explicit_ Kette verwenden, die immer manuell ausgepackt werden sollte. –

1

Wenn Sie nach einer einzigen Kette sind, nicht in lodash sein kann, aber in der reinen JS dies ist ein Weg, um die Aufgabe zu erfüllen.

var arr = [ 
 
      { 
 
        aProp: '1', 
 
      anotherProp: '2', 
 
       thirdProp: '3', 
 
      someProperty: { 
 
          id: 1, 
 
          name: "john" 
 
          } 
 
      }, 
 
      { 
 
        aProp: '3', 
 
      anotherProp: '4', 
 
       thirdProp: '5', 
 
      someProperty: { 
 
          id: 1, 
 
          name: "john" 
 
          } 
 
      }, 
 
      { 
 
        aProp: '2', 
 
      anotherProp: 'f', 
 
       thirdProp: '6', 
 
      someProperty: { 
 
          id: 2, 
 
          name: "tom" 
 
          } 
 
      }, 
 
      { 
 
        aProp: 't', 
 
      anotherProp: 'g', 
 
       thirdProp: 'f', 
 
      someProperty: { 
 
          id: 3, 
 
          name: "yacob" 
 
          } 
 
      }, 
 
     ], 
 

 
    red = arr.reduce((p,c) => {!~p[0].indexOf(c.someProperty.id) && (p[0].push(c.someProperty.id), p[1].push(c.someProperty.name)); return p}, [[],[]]).reduce((p,c) => p.map((n,i) => ({id:n,name:c[i]}))); 
 

 
document.write("<pre>" + JSON.stringify(red,null,2) + "</pre>");

Dann habe ich es ein wenig mehr darüber nachgedacht, und ich nehme an, die folgend ein anderer Weg ist, diese Aufgabe mit reinem JS zu tun.

red = arr.map(e => ({id: e.someProperty.id, name: e.someProperty.name})).reduce((p,c) => {!~p[0].indexOf(c.id) && (p[0].push(c.id), p[1].push(c)); return p},[[],[]])[1]; 

würde ich l Liebe einen Leistungsvergleich von ihnen zu sehen ...

+0

Diese Lösung funktioniert, aber es scheint nicht, sehr elegant. Ich habe wirklich versucht, Lodash einfach so zu benutzen, wie es beabsichtigt war; Ich bin mir nicht sicher, ob meine anfängliche Antwort das tut. –

+0

@ Doug S. Nun, Sie haben recht, es war nicht so elegant, aber ich habe ein wenig mehr Gedanken gegeben und reduzierte meine Lösung auf eine einzige Kette von zwei reduziert in reinem JS. Ich mochte es auf diese Weise :) – Redu