简体   繁体   English

如何使用 lodash 从嵌套的 object 中获取唯一数组

[英]How to get unique array from nested object with lodash

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我想得到一组唯一的操作名称和 label 如下所示

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?有人可以建议实现这一目标的最佳方法吗?

This can be easily done without lodash .这可以在没有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:您可以先将数据展平,然后将map作为键值对,然后使用Map删除重复的条目:

 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:或者如果您不想使用Map则使用filter方法:

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

Use _.flatMap() to get a flattened array of operations , and then use _.uniqBy() to get only items with unique name :使用_.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 = _.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 :使用 lodash/fp,您可以使用_.flow()生成 function 来展平operations ,然后按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>

There is no need for loadash, a simple Map object, will allow you to suppress the duplicates.不需要加载,一个简单的Map object 将允许您抑制重复项。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM