Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping Array of objects and only taking unique

Is there a more elegant way to write this line of code?

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

it seems like I should be able to chain it, instead of nesting the lodash .uniqBy call inside of the .chain call.

I would expect the following to work, but it wont.

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

The input is:

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

The output should be:

[{id:1, name:"john"},{id:2, name:"tom"},{id:3, name:"yacob"}]
like image 864
Doug S. Avatar asked May 25 '26 01:05

Doug S.


2 Answers

Actually, you are on the right track:

_.chain(data).map('someProperty').uniqBy('id').value()
like image 127
Роман Парадеев Avatar answered May 26 '26 14:05

Роман Парадеев


If you are after a single chain, may be not in lodash but in pure JS this is a way to accomplish the task.

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

Then i have given it a little more thought and i suppose the following is another way to do this job with pure 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];

I would l love to see a performance comparison of these...

like image 26
Redu Avatar answered May 26 '26 15:05

Redu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!