【问题标题】:Remove duplicates from NESTED array of objects从 NESTED 对象数组中删除重复项
【发布时间】:2021-05-11 12:57:23
【问题描述】:

我有一个如下所示的对象数组,其中包含另一个对象数组,这些对象具有重复的 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"
                }
              ]
            }
          ]
        }
      ]

我尝试了几种解决方案,其中一些不起作用,但一个起作用,我将其复制/粘贴在下面。我已经设法将它们全部存储在一个对象数组中,只是代码在我看来真的很糟糕。我正在尝试找到一个更清洁的解决方案来解决这个问题。这是我的解决方案,我想看看它与您的解决方案相比如何,如果您能给我一些反馈,那将是非常棒的。

    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)

我想要得到的是这样的东西,基本上,只是在 verticals 数组中找到的所有对象,但是 - 没有重复:

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

大家加油!

【问题讨论】:

  • 定义重复。垂直?那么留下哪个 progName 呢?还是 progName 无关紧要?你希望你的最终数组是什么样子的?
  • 嗨,我更新了问题。它是嵌套的“垂直”数组内的verticalName inside键。没关系,我只需要将所有不重复的值存储在一个对象数组中。

标签: javascript reactjs lodash


【解决方案1】:

你可以通过纯 ES6 函数来实现,我会分解,但你可以在一行中拥有它:)

首先,您需要检索所有的verticalNames

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

你会有很多数组或数组,所以我们需要将所有这些都展平

const flattened = allVerticalNames.flat(2)

此时您拥有所有的verticalNames,但没有uniq。为此,我们应该将其转换为 Set、Map 或更简单的 Object

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

此时你有一个像{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}))

就是这样!

都在一条线上?

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

【讨论】:

  • 根据问题中的预期结果,我认为 OP 只是希望从嵌套数组中消除重复项,唯一值不一定取决于 @987654327 根级别的垂直值@ 大批。您的回答很好,但输出包括Law and Criminology,这不在预期结果中。
  • 我认为我们需要所有程序中的所有 uniq 值。我们可以很容易地调整逻辑以删除每个程序中的重复项;)
  • 老实说最干净的解决方案,对每个步骤都有很好的解释
【解决方案2】:

您可以在此用例中使用 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(duplicate);
        return !duplicate;
      });

      console.log(filteredArr);
      

【讨论】:

    【解决方案3】:

    如果我正确理解了这个问题,我们需要从嵌套的 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);

    更新:

    根据问题中的预期结果更新了代码 sn-p。

    这个想法是首先找到嵌套的程序数组,这是通过基于.length过滤landingPages对象来完成的

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

    然后,我们创建一个集合来跟踪这个嵌套数组中的所有唯一程序,

    const uniqueprogrammes = new 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];
      }
    })
    

    但是,这会给我们如下输出,

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

    所以(最后),我们需要用filter 取出虚假值,

    .filter(v => !!v);
    

    【讨论】:

      【解决方案4】:

      您可以使用 loadash 来修饰,然后删除重复项。





      var arrayWithDuplicatesRemoved=.flattenDeep(landingPages);

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

      【讨论】:

      • 为基本的 JS 功能推荐外部库并不理想。
      • @BrainFooLong 问题被标记为lodash
      猜你喜欢
      • 2017-04-10
      • 2016-03-12
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多