【问题标题】:How to prevent duplicate items in array?如何防止数组中的重复项?
【发布时间】:2020-01-24 19:47:00
【问题描述】:

我有两个数组,我想将一些项目从 arr1 推送到 arr2 以防止重复,因为我已经向 arr2 添加了一些项目,这些项目也在 arr1 中。我在 react js 中这样做

                arr1.forEach(q1 => {
                    arr2.forEach(q2 => {
                        if (q1.lessonId !== q2.lessonId) {
                            if (q2.obtainedMarks >= q2.passingMarks) {
                                User.findByIdAndUpdate(req.body.userId, { $push: { arr1: { $each: 
                                    [q2._id] } } }, (err, doc) => {

                                })
                            }
                        }
                    })
                });

【问题讨论】:

    标签: javascript arrays reactjs filter duplicates


    【解决方案1】:

    您可以使用集合而不是数组。它们具有防止重复条目的内置功能。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

    【讨论】:

      【解决方案2】:

      我不知道你的 User.findByIdAndUpdate$push 做了什么,但如果你只是想在第一个数组中组合第二个数组中的非重复项,只有当标记比较有效时,你可以写一些东西像这样:

      const addWithoutDups = (arr1, arr2, ids = new Set (arr1 .map (x => x .lessonId))) => 
        [
          ...arr1, 
          ...arr2.filter((x) => !ids .has (x .lessonId) && x .obtainedMarks > x .passingMarks)
        ]
      
      const arr1 = [
        {lessonId: 1, more: 'here...'}, 
        {lessonId: 2, more: 'here...'}, 
        {lessonId: 3, more: 'here...'}, 
        {lessonId: 4, more: 'here...'}
      ]
      const arr2 = [
        {lessonId: 2, obtainedMarks: 10, passingMarks: 7},
        {lessonId: 3, obtainedMarks: 5, passingMarks: 12},
        {lessonId: 5, obtainedMarks: 10, passingMarks: 6},
        {lessonId: 7, obtainedMarks: 13, passingMarks: 8},
        {lessonId: 11, obtainedMarks: 10, passingMarks: 15},
      ]
      
      console .log (
        addWithoutDups (arr1, arr2)
      )

      请注意,id 23 被拒绝为重复,id 11 不合格,但 id 57 被正确添加。

      另请注意,这会返回一个包含您的数据的新数组;它不会改变原件。 (我不会参与这种猥亵的!)

      【讨论】:

      • 先生,我想在过滤所有条件后将 id 推送到 arr1。我该怎么办?
      • @AdnanBabai:如果你想改变arr1,那么你就得问别人了。我总是喜欢使用不可变数据。
      • @ScottSauyet 在 React 中尝试和变异不是一个好主意。我不知道您的其余代码,但似乎不需要突变 arr1 。只需在答案中使用 concat 或 spread 即可。
      • @HMR,这是给 OP 的吗?
      • 是的,它是给@AdnanBabai,所以在移动设备上很难阅读,我复制了错误的名称(再次)
      【解决方案3】:

      您创建一个 arr1 课程 ID 的 Set,然后使用数组过滤器过滤掉 arr2 中已经在 arr1 中的所有内容,然后再次过滤以仅获取通过的项目:

      //get all lessonId for arr1 in a Set
      const arr1Ids = new Set(arr1.map(x=>x.lessonId));
      //get items of arr2 that are not already in arr1
      const passingArr2NotInArr1 = arr2
        .filter(
          //take out everything that is already in arr1
          item => !arr1Ids.has(item.lessonId)
        )
        .filter(
          //only when it passed
          item => item.obtainedMarks >= item.passingMarks
        );
      

      【讨论】:

      • 不是什么简单的方法吗?
      • 在 arr1 中有多个具有课程 ID 的对象
      • @AdnanBabai 仅使用您的代码使用的代码:if (q1.lessonId !== q2.lessonId) { 使用 Set 的另一个答案可能更快。
      • 谢谢@HRM。它的工作。你能详细解释一下吗?我在理解方面遇到困难
      • A Map 拥有 arr1 的所有课程 ID,使用 filter 从 arr2 中取出 arr1 中的课程,然后再次过滤以获取具有足够分数的课程。我会更新我的答案,因为 Set 可能比 map 更好。
      【解决方案4】:

      如果项目相同 -> 它们具有相同的引用,请使用 Set 作为 Sokushinbutsu 的答案

      如果没有,请使用Array.prototype.some()

      const arr1Difference = arr1.filter((arr1Item) => {
         const isSomeInArr2 = arr2.some((arr2Item) => {
              return arr1Item.lessonId === arr2Item.lessonId
              // return arr1Item === arr2Item (In the case that items are same -> they have same reference)
         })
      
         return !isSomeInArr2 
      })
      
      const arr2AddToArr1Difference = [...arr2, ...arr1Difference ]
      

      【讨论】:

      • 这是一种低效的过滤方式。对于 arr2 中的每个项目,您都在 arr1 中进行查找。
      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      相关资源
      最近更新 更多