简体   繁体   English

从 NESTED 对象数组中删除重复项

[英]Remove duplicates from NESTED array of objects

I have an array of objects like below, which inside of it has another array of objects which has duplicate verticalName values that need to be removed in order to be displayed on the page.我有一个像下面这样的对象数组,其中有另一个对象数组,这些对象具有重复的verticalName值,需要删除这些值才能在页面上显示。

 "landingPages": [
        {
          "programmes": [
            {
              "progName": "Programme 1",
              "verticals": [
                {
                  "id": "8",
                  "verticalName": "Law and Criminology"
                }
              ]
            }
          ]
        },
        {
          "programmes": [
            {
              "progName": "Programme 2",
              "verticals": [
                {
                  "id": "1",
                  "verticalName": "Psychology and Sociology"
                }
              ]
            }
          ]
        },
        {
          "programmes": [
            {
              "progName": "Programme 3",
              "verticals": [
                {
                  "id": "3",
                  "verticalName": "Computing and IT"
                }
              ]
            }
          ]
        },
        {
          "programmes": [
            {
              "progName": "Programme 4",
              "verticals": [
                {
                  "id": "1",
                  "verticalName": "Psychology and Sociology"
                }
              ]
            },
            {
              "progName": "Programme 5",
              "verticals": [
                {
                  "id": "3",
                  "verticalName": "Computing and IT"
                }
              ]
            },
            {
              "progName": "Programme 6",
              "verticals": [
                {
                  "id": "2",
                  "verticalName": "Business and Management"
                }
              ]
            },
            {
              "progName": "Programme 7",
              "verticals": [
                {
                  "id": "3",
                  "verticalName": "Computing and IT"
                }
              ]
            },
            {
              "progName": "Programme 8",
              "verticals": [
                {
                  "id": "3",
                  "verticalName": "Computing and IT"
                }
              ]
            }
          ]
        }
      ]

I have tried couple of solutions, some of the did not work but one did, which I copy/pasted below.我尝试了几种解决方案,其中一些不起作用,但一个起作用,我在下面复制/粘贴。 I've managed to store all of them inside of one array of objects, it's just that the code to me looks really bad.我已经设法将它们全部存储在一个对象数组中,只是代码对我来说看起来很糟糕。 I am trying to find a cleaner solution to this problem.我正在尝试找到一个更清洁的解决方案来解决这个问题。 Here is my solution and I would like to see how does it compare to your solutions maybe, and if you could give me some feedback that would be amazing.这是我的解决方案,我想看看它与您的解决方案相比如何,如果您能给我一些反馈,那将是惊人的。

    let known = {}
    let noduplicates = programmes.map((subarray) => {
        const newarrays = []
        subarray.verticals.forEach((item) => {
            if (
                !known.hasOwnProperty(item.verticalName) &&
                (known[item.verticalName] = true)
            ) {
                newararys.push(item)
            } else {
                console.log('test')
            }
        })
        console.log(newarrays)
        return newarrays
    })
    const fil = filtered.filter((item) => item.length)
    const singleArr = fil.reduce((a, b) => a.concat(b), [])
    console.log(singleArr)

What I am trying to get is something like this, basically, just all the objects that were found inside of verticals array, but - without duplicates:我想要得到的是这样的东西,基本上,只是在垂直数组中找到的所有对象,但是 - 没有重复:

[
   {id: "1", verticalName: "Psychology and Sociology"}, 
   {id: "3", verticalName: "Computing and IT"}, 
   {id: "2", verticalName: "Business and Management"}
]

Cheers everyone!大家加油!

You could achieve it by pure ES6 functions, I'll decompose, but you can have it all in one line:)你可以通过纯 ES6 函数来实现,我会分解,但你可以在一行中拥有它:)

first, you need to retrieve all verticalNames首先,您需要检索所有verticalNames

const allVerticalNames = landingPages.map(lp => lp.programmes.map(p => p.verticals))

You'll have plenty arrays or arrays, so we need to flatten all of this你会有很多 arrays 或 arrays,所以我们需要将所有这些都展平

const flattened = allVerticalNames.flat(2)

At this point you have all your verticalNames, but not uniq.此时您拥有所有的verticalNames,但没有uniq。 To do that, we should convert it to a Set, Map or easier, an Object为此,我们应该将其转换为 Set,Map 或更简单的 Object

const keyValuePairs = flattened.map(v => [v.id, v.verticalName]); // We transform to a pair key / value
const uniq = Object.fromEntries(keyValuePairs)

At this point you have an object like {1: "Psychology and Sociology", 2: "Business and Management", 3: "Computing and IT", 8: "Law and Criminology"} So if you want to have it back to the way in exemple, you move it back to an array!此时你有一个 object 像{1: "Psychology and Sociology", 2: "Business and Management", 3: "Computing and IT", 8: "Law and Criminology"}所以如果你想让它回到例如,您将其移回数组!

const final = Object.entries(uniq).map(([id, verticalName]) => ({id, verticalName}))

And that's it!就是这样!

All in one line?全部在一条线上?

const final = Object.entries(Object.fromEntries(landingPages.map(lp => lp.programmes.map(p => p.verticals)).flat(2).map(v => [v.id, v.verticalName]))).map(([id, verticalName]) => ({id, verticalName}))

You may use set for this use case which lets you store unique values of any type.您可以将set用于此用例,它允许您存储任何类型的唯一值。

 const data = [ { "programmes": [ { "progName": "Programme 1", "verticals": [ { "id": "8", "verticalName": "Law and Criminology" } ] } ] }, { "programmes": [ { "progName": "Programme 2", "verticals": [ { "id": "1", "verticalName": "Psychology and Sociology" } ] } ] }, { "programmes": [ { "progName": "Programme 3", "verticals": [ { "id": "3", "verticalName": "Computing and IT" } ] } ] }, { "programmes": [ { "progName": "Programme 4", "verticals": [ { "id": "1", "verticalName": "Psychology and Sociology" } ] }, { "progName": "Programme 5", "verticals": [ { "id": "3", "verticalName": "Computing and IT" } ] }, { "progName": "Programme 6", "verticals": [ { "id": "2", "verticalName": "Business and Management" } ] }, { "progName": "Programme 7", "verticals": [ { "id": "3", "verticalName": "Computing and IT" } ] }, { "progName": "Programme 8", "verticals": [ { "id": "3", "verticalName": "Computing and IT" } ] } ] } ]; const seen = new Set(); const filteredArr = data.filter(el => { const verticalName = el.programmes[0].verticals[0].verticalName; const duplicate = seen.has(verticalName); seen.add(verticalName); return;duplicate; }). console;log(filteredArr);

If I understand the question correctly, we need to remove the verticalNames from the nested programmes array.如果我正确理解了这个问题,我们需要从嵌套programmes数组中删除verticalNames

 const landingPages = [ { programmes: [ { progName: 'Programme 1', verticals: [ { id: '8', verticalName: 'Law and Criminology', }, ], }, ], }, { programmes: [ { progName: 'Programme 2', verticals: [ { id: '1', verticalName: 'Psychology and Sociology', }, ], }, ], }, { programmes: [ { progName: 'Programme 3', verticals: [ { id: '3', verticalName: 'Computing and IT', }, ], }, ], }, { programmes: [ { progName: 'Programme 4', verticals: [ { id: '1', verticalName: 'Psychology and Sociology', }, ], }, { progName: 'Programme 5', verticals: [ { id: '3', verticalName: 'Computing and IT', }, ], }, { progName: 'Programme 6', verticals: [ { id: '2', verticalName: 'Business and Management', }, ], }, { progName: 'Programme 7', verticals: [ { id: '3', verticalName: 'Computing and IT', }, ], }, { progName: 'Programme 8', verticals: [ { id: '3', verticalName: 'Computing and IT', }, ], }, ], }, ] let page = landingPages.find(page => page.programmes.length > 1); const uniqueprogrammes = new Set(); const uniqueverticals = page.programmes.map(p => { const vn = p.verticals[0].verticalName; if (.uniqueprogrammes.has(vn)) { uniqueprogrammes;add(vn). return p;verticals[0]. } });filter(v =>.;v); console.log(uniqueverticals);

UPDATE:更新:

Updated code snippet based on the expected outcome in the question.根据问题中的预期结果更新了代码片段。

The idea is to first find the nested array of programmes which is done by filtering the landingPages object based on the .length这个想法是首先找到嵌套的程序数组,这是通过根据.length过滤landingPages object 来完成的

let page = landingPages.find(page => page.programmes.length > 1);

Then, we create a set to keep a track of all the unique programmes from this nested array,然后,我们创建一个集合来跟踪这个嵌套数组中的所有唯一程序,

const uniqueprogrammes = new Set();

Next, we map through the nested array and find all the verticals that are not a part of the uniqueprogrammes set,接下来,我们通过嵌套数组map找到所有不属于uniqueprogrammes集的垂直,

const uniqueverticals = page.programmes.map(p => {
  const vn = p.verticals[0].verticalName;
  if (!uniqueprogrammes.has(vn)) {
    uniqueprogrammes.add(vn);
    return p.verticals[0];
  }
})

However, this will gives us an output like the following,但是,这会给我们一个 output 如下所示,

[
  { id: '1', verticalName: 'Psychology and Sociology' },
  { id: '3', verticalName: 'Computing and IT' },
  { id: '2', verticalName: 'Business and Management' },
  undefined,
  undefined
]

so (lastly), we need to filter out the falsy values with,所以(最后),我们需要filter掉虚假值,

.filter(v => !!v);

You can use loadash to flatter and then remove duplicates.您可以使用loadash来奉承然后删除重复项。





var arrayWithDuplicatesRemoved= .flattenDeep(landingPages); var arrayWithDuplicatesRemoved= .flattenDeep(landingPages);

arrayWithDuplicatesRemoved = arrayWithDuplicatesRemoved .uniqBy(data, function (e) {return e.verticalName;}); arrayWithDuplicatesRemoved = arrayWithDuplicatesRemoved .uniqBy(data, function (e) {return e.verticalName;});

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

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