【问题标题】:how do filter duplicate object in a array using JavaScript and return with a flag?如何使用 JavaScript 过滤数组中的重复对象并返回一个标志?
【发布时间】:2022-01-25 01:18:20
【问题描述】:

我有一个对象数组,我需要根据返回时的两个键过滤重复项,上面有额外的键

let word = [
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    name: "alex",
  },
];

在上面的示例中,我想根据开始键和结束键过滤掉重复项,如果同一个对象有重复项,则还需要添加一个名为 hasDuplicate 的键

let filterd = [
  {
    start: 5,
    end: 8,
    name: "sam",
  },
  {
    start: 85,
    end: 114,
    name: "Abhishek",
  },
  {
    start: 1,
    end: 4,
    haveDuplicate: true,
    name: "alex",
  },
];


我尝试了 lodash,但我无法添加额外的密钥 以下是我尝试过的

_.uniqBy(data, obj => obj.start && obj.end);

【问题讨论】:

    标签: javascript filter lodash


    【解决方案1】:

    你可以结合 reduce 和 Object.values

    Object.values(word.reduce( (a,x) => { if(a[x.start+'-'+x.end]) x = {...x, haveDuplicate: true}; return a[x.start+'-'+x.end]=x,a} ,  {} ))
    

    【讨论】:

      【解决方案2】:

      您可以使用Array.prototype.reduce() 并使用Array.prototype.find() 检查该项目是否存在,如下所示:

      let word = [
        {
          start: 1,
          end: 4,
          name: "alex",
        },
        {
          start: 5,
          end: 8,
          name: "sam",
        },
        {
          start: 1,
          end: 4,
          name: "alex",
        },
        {
          start: 85,
          end: 114,
          name: "Abhishek",
        },
        {
          start: 1,
          end: 4,
          name: "alex",
        },
      ];
      
      const filteredArr = word.reduce((acc, curr) => {
        const obj = acc.find(item => item.start === curr.start && item.end === curr.end);
        if(obj) {
          if(!obj.haveDuplicate) {
            obj.haveDuplicate = true;
          }
          return acc;
        }
        
        acc.push(curr);
        return acc;
      }, []);
      
      console.log(filteredArr);

      Array.prototype.reduce()
      Array.prototype.find()

      【讨论】:

      • 每次迭代都使用find() 效率不高。跟踪已经看到的内容要高效得多,并且不需要多次迭代
      【解决方案3】:

      你可以使用数组过滤器,

      您可以根据您的用例更新密钥。

      const word = [
        {
          start: 1,
          end: 4,
          name: "alex",
        },
        {
          start: 5,
          end: 8,
          name: "sam",
        },
        {
          start: 1,
          end: 4,
          name: "alex",
        },
        {
          start: 85,
          end: 114,
          name: "Abhishek",
        },
        {
          start: 1,
          end: 4,
          name: "alex",
        },
      ];
      
      const map = {};
      const res = word.filter((item) => {
        const key = item.start + "-" + item.end;
        if (!map[key]) {
          map[key] = true;
          return true;
        }
        return false;
      });
      
      console.log(res);

      【讨论】:

        【解决方案4】:

        要使用_.uniquBy(),您需要一个函数来从每个可用于比较的元素中返回一个值。

        这不会解决如何添加haveDuplicate 属性,而只是展示如何使用该特定方法

        const concatStartEnd = (o) => `${o.start}|${o.end}`;
        
        console.log(_.uniqBy(word, concatStartEnd))
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script>
        let word=[{start:1,end:4,name:"alex"},{start:5,end:8,name:"sam"},{start:1,end:4,name:"alex"},{start:85,end:114,name:"Abhishek"},{start:1,end:4,name:"alex"}];
        </script>

        【讨论】:

          【解决方案5】:

          这里有个idea,使用_.groupBy,我们可以读取group中的item数来判断是否有重复。

          let word = [
            {
              start: 1,
              end: 4,
              name: "alex",
            },
            {
              start: 5,
              end: 8,
              name: "sam",
            },
            {
              start: 1,
              end: 4,
              name: "alex",
            },
            {
              start: 85,
              end: 114,
              name: "Abhishek",
            },
            {
              start: 1,
              end: 4,
              name: "alex",
            },
          ];
          
          const grouped = _.groupBy(word, o => `${o.start}-${o.end}`);
          
          const result = _.map(grouped, occurrences => {
            if (occurrences.length > 1) return { ...occurrences[0], haveDuplicate: true };
            return occurrences[0];
          })
          
          console.log(result);
          &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"&gt;&lt;/script&gt;

          【讨论】:

            猜你喜欢
            • 2019-01-22
            • 2021-02-26
            • 1970-01-01
            • 2018-08-27
            • 2021-12-12
            • 1970-01-01
            • 2021-05-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多