如何从数组中删除重复值?当数组内的对象属性未定义时,我的代码失败
Posted
技术标签:
【中文标题】如何从数组中删除重复值?当数组内的对象属性未定义时,我的代码失败【英文标题】:How to remove duplicate values from an Array? My code fails when object property inside the array is undefined 【发布时间】:2021-07-18 07:29:56 【问题描述】:我期待一个通用的解决方案,包括作为数组元素的高阶对象。
const input1 = [1,2,4,6,'4','1',a:1,a:1]; //my code works
const input2 = [1,2,4,6,'4','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));
【问题讨论】:
JSON.stringify()
删除 JSON 字符串中具有 undefined
、function
和其他无效值的键。 JSON.stringify( a:undefined )
是“”`
我知道。如果我删除 JSON.stringify(),那么我将无法从 Array 中删除重复的对象。
如果您不关心对象中键的顺序或 null 和 undefined 被视为相同,则可以将 JSON.stringify(Object.entries(value))
用于对象。
见这里:levelup.gitconnected.com/…
【参考方案1】:
包括 lodash https://cdnjs.com/libraries/lodash.js 或 https://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,2,4,6,'4','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, 2, 4, 6, a: 1 ]
input2
- [ 1, 2, 4, 6, a: undefined , b: undefined ]
现场示例https://jsfiddle.net/9cx4kget/
【讨论】:
你能提供一个CDN链接来在我的html中添加loadash吗? 更新了答案。示例jsfiddle.net/knrm7q2f @SupritBeck 如果您的数组中有undefined
或null
,此代码将失败:[1,2,4,6,true,'4','1','hello', '你好',null,undefined,a:undefined,b:a:undefined,b:a:undefined]
@AlanTishin instanceof
验证 value 的原型,因此,如果 Object 是通过 Object.create(null)
创建的 - 这将返回 false
,请查看我的回复,了解如何检查 value 是否为 @987654335 @【参考方案2】:
原版解决方案
const input2 = [
1,2,4,6,
true,
'4','1',
'hello','hello',
null,
undefined,
a: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,
2,
4,
6,
true,
"hello",
null,
undefined,
"a": null
,
"b":
"a": null,
"b": "hello"
]
*/
【讨论】:
你能展示一下Set
的方法是什么样的吗?
当然,您的数组中可能包含什么样的数据?对象、字符串、数字、字符串化数字,还有什么?
适用于所有数据类型。不要忘记布尔值。
@SupritBeck 只需打开控制台并点击Run code snippet
在对象情况下,此解决方案取决于对象键顺序。示例[b:b: undefined, a:undefined, b:a:undefined, b: undefined];
将不会重复数据删除以上是关于如何从数组中删除重复值?当数组内的对象属性未定义时,我的代码失败的主要内容,如果未能解决你的问题,请参考以下文章