2

My collection contains the following (array of objects):

[
    {
        id: 'id-1',
        uniqueName: 'operation-level-1',
        operations: [
            {
                name: 'operaion-1',
                label: 'operation-1-label'
            },
            {
                name: 'operaion-2',
                label: 'operation-2-label'
            }
        ]
    },
    {
        id: 'id-2',
        uniqueName: 'operation-level-2'
        operations: [
            {
                name: 'operaion-1',
                label: 'operation-1-label'
            },
            {
                name: 'operaion-3',
                label: 'operation-3-label'
            }
        ]
    }

]

I wanted to get an array of unique operation name and label as shown below

const result = [
    {
        name: 'operaion-1',
        label: 'operation-1-label'
    },
    {
        name: 'operaion-2',
        label: 'operation-2-label'
    },
    {
        name: 'operaion-3',
        label: 'operation-3-label'
    }
]

Can someone suggest the best way to achieve this, please?

1
  • The best way is the implemented code which works. Can you show what you've already done for this? Commented Jun 9, 2020 at 9:36

3 Answers 3

6

This can be easily done without lodash. You can first flat the data then map it as a key value pair and then make use of Map to remove the duplicate entries:

var data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];

var result =  [...new Map(data.flatMap(({operations})=>operations).map(k=>([k.name, k]))).values()];

console.log(result);

Or if you do not want to use Map then use filter method:

var data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];

var result = data.flatMap(({operations})=>operations).filter((val,i,self)=>self.findIndex(j=>j.name==val.name && j.label==val.label)==i);

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

5

Use _.flatMap() to get a flattened array of operations, and then use _.uniqBy() to get only items with unique name:

const data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];

const result =  _.uniqBy(
  _.flatMap(data, 'operations'),
  'name'
);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

With lodash/fp you can generate a function using _.flow() that flattens operations, and then get the unique values by name:

const fn = _.flow(
  _.flatMap('operations'),
  _.uniqBy('name')
)

const data=[{ id: 'id-1', uniqueName: 'operation-level-1', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-2', label: 'operation-2-label' } ] }, { id: 'id-2', uniqueName: 'operation-level-2', operations: [ { name: 'operaion-1', label: 'operation-1-label' }, { name: 'operaion-3', label: 'operation-3-label' } ] }];

const result = fn(data);

console.log(result);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

Comments

0

There is no need for loadash, a simple Map object, will allow you to suppress the duplicates.

const arr = [{
    id: 'id-1',
    uniqueName: 'operation-level-1',
    operations: [{
        name: 'operaion-1',
        label: 'operation-1-label'
      },
      {
        name: 'operaion-2',
        label: 'operation-2-label'
      }
    ]
  },
  {
    id: 'id-2',
    uniqueName: 'operation-level-2',
    operations: [{
        name: 'operaion-1',
        label: 'operation-1-label'
      },
      {
        name: 'operaion-3',
        label: 'operation-3-label'
      }
    ]
  }
];

// Go thought the arr and add all the name/label into the map
// Then use Array.from to reformate the Map into the wanted format
const uniqueArr = Array.from(arr.reduce((tmp, {
  operations,
}) => {
  operations.forEach(({
    name,
    label,
  }) => {
    tmp.set(name, label);
  });

  return tmp;
}, new Map())).map(([name, label]) => ({
  name,
  label,
}));

console.log(uniqueArr);

Comments

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.