2016-04-26 4 views
2

Есть ли более элегантный способ написать эту строку кода?Сопоставление массива объектов и использование только уникальных

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

кажется, что я должен быть в состоянии цепи его, вместо того, чтобы гнездиться на lodash .uniqBy называют внутри вызова .chain.

Я ожидаю, что следующее будет работать, но это не будет.

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

вход является:

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" 
     } 
    }, 
]; 

Вывод должен быть:

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

ответ

2

На самом деле, вы находитесь на правильном пути:

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

Также вам не нужно иметь 'цепочку', которую вы можете сделать:' _ (data) .map ('someProperty'). UniqBy ('id'). Value() ' – Mike

+0

In в какой ситуации вам понадобится использовать цепочку? –

+1

'_ (data)' является цепочкой _implicit_, поэтому мы не должны вызывать 'value', если последний метод возвращает один объект:' _ (data) .map ('someProperty'). UniqBy ('id'). Get (0) '. Если это поведение нежелательно или мы хотим совместить интерфейс подчеркивания, мы могли бы использовать цепочку _explicit_, которая всегда должна быть развернута вручную. –

1

Если вы после одной цепи, может быть не в lodash, но в чистом JS это способ выполнить задачу.

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>");

Тогда я дал ему немного больше мысли и я полагаю, что следующий другой способ сделать эту работу с чистым JS.

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]; 

Я бы л любовь, чтобы увидеть сравнение производительности этих ...

+0

Это решение работает, но это не кажется очень элегантно. Я действительно пытался просто использовать lodash в том виде, в котором он был предназначен; Я не уверен, что мой первоначальный ответ делает это. –

+0

@ Doug S. Ну, вы правы, но это было не так элегантно, но я дал немного больше мысли и уменьшил свое решение до одной цепочки из двух уменьшений в чистом JS. Мне это действительно понравилось :) – Redu

Смежные вопросы