微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从数组中删除重复值?当数组内的对象属性未定义时,我的代码失败

如何解决如何从数组中删除重复值?当数组内的对象属性未定义时,我的代码失败

我期待一个通用的解决方案,包括作为数组元素的高阶对象。

const input1 = [1,2,4,6,'4','1',{a:1},{a:1}]; //my code works
const input2 = [1,{a:undefined},{b:undefined}]; //my code fails.
    
function deDuplicate(arr) {
  let obj = {};
  arr.forEach(value => {
    if (!obj[JSON.stringify(value) + typeof value]) obj[JSON.stringify(value) + typeof value] = value;
  });
  return Object.values(obj);
}

console.log(deDuplicate(input2));

解决方法

包括 lodash https://cdnjs.com/libraries/lodash.jshttps://www.jsdelivr.com/package/npm/lodash

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

    const input1 = [1,2,4,6,'4','1',{a:1},{a:1}]; //my code works
    const input2 = [1,{a:undefined},{b:undefined}]; //my code fails.

    function deDuplicate(arr) {
        let res = []
        for(const el of arr) {
            const dublicateIndex = res.findIndex( (el2) => {

                // if both nulls
                if( _.isNull(el) && _.isNull(el2) ) {
                    return true
                }

                // if both undefined
                if( _.isUndefined(el) && _.isUndefined(el2) ) {
                    return true
                }


                // check both are string,or numbers
                if(
                    ( _.isNumber(el) || _.isString(el)) &&
                    ( _.isNumber(el2) || _.isString(el2) )
                ) {

                    return el.toString() === el2.toString()
                }

                // check if one is object,other not
                if(_.isObject(el) !== _.isObject(el2)) {
                    return false
                }

                // check both is object
                if(_.isObject(el) === _.isObject(el2)) {
                    return _.isEqual(el,el2)
                }

                return _.isEqual(el,el2)
            })

            if(dublicateIndex === -1) {
                res.push(el)
            }
        }
        return res
    }

    console.log(deDuplicate(input3));

input1 - [ 1,{ a: 1 } ]

input2 - [ 1,{ a: undefined },{ b: undefined } ]

现场示例https://jsfiddle.net/9cx4kget/

,

香草解决方案

const input2 = [
  1,true,'hello',null,undefined,{b:{a:undefined,b:'hello'}},{b:{b:'hello',a:undefined}}
];

const unduplicatedInput2 = new Set(input2.map(value => {
  const isString = "string" === typeof value;
  if(isString) {
    const nValue = Number(value);
    const isNumber = nValue || 0 === nValue;
    if(isNumber) {
      return nValue;
    }
  }
  
  return value;
}));

console.log(unduplicatedInput2);

const isObject = (o) => null !== o && 'object' === typeof o;

const sortObjectKeys = (obj) => {
  const entries = Object.entries(obj);
  const sortedEntries =
    entries.sort(([a],[b]) => (a > b) - (a < b));
  
  const deepSort = sortedEntries
    .map(([key,value]) => {
      if (isObject(value)) {
        return [key,sortObjectKeys(value)];
      }
      return [key,value];
    });
    
  return Object.fromEntries(deepSort);
}

const duplicateObjectRemoval = (array) => {
  const extractedObjects = array
    .filter(a => isObject(a));

  const arrayWithNoObjects = array
    .filter(a => !isObject(a));
    
  const replacer = (key,value) =>
    'undefined' === typeof value ? null : value;
    
  const sortedExtractedObjects =
    extractedObjects.map(o => sortObjectKeys(o));
    
  const uniqueObjects = [...new Set(
    sortedExtractedObjects.map(o => JSON.stringify(o,replacer))
  )].map(s => JSON.parse(s));
    
  return [...arrayWithNoObjects,...uniqueObjects];
}

console.log(duplicateObjectRemoval([...unduplicatedInput2]));

/*
[
  1,"hello",{
    "a": null
  },{
    "b": {
      "a": null,"b": "hello"
    }
  }
]
*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。