3

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

2 Answers 2

3

Actually, you are on the right track:

_.chain(data).map('someProperty').uniqBy('id').value()
Sign up to request clarification or add additional context in comments.

3 Comments

Also you don't need to have chain you can do: _(data).map('someProperty').uniqBy('id').value()
In what situation would you need to use chain?
_(data) is an implicit chain, so we should not call value if the last method returns a single object: _(data).map('someProperty').uniqBy('id').get(0). If this behaviour is undesirable or we want to match underscore's interface we could use an explicit chain, which should always be unwrapped manually.
1

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...

2 Comments

This solution works, but it doesn't seem very elegant. I was really trying to just use lodash in the way it was intended; I'm not sure my initial answer does that.
@ Doug S. Well you are right it was not as elegant however i have given a little more thought and reduced my solution to a single chain of two reduces in pure JS. I actually liked it this way :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.