Javascript:使用单个属性删除对象数组中的重复项



我有这样的对象,其中"id"是唯一的。在任何低于ES5的版本中,我都需要从javascript中的对象数组中删除重复项。我需要根据id字段进行比较,并删除其重复项。

示例:

Object = [
{id: id_one, value: value_one, label: ABC},
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

输出:

result = [
{id: id_one, value: value_one, label: ABC},
{id: id_three, value: value_three, label: ABX},
{id: id_two, value: value_two, label: ABY},
{id: id_four, value: value_four, label: ABD}
];

我试过这样的逻辑,

function getDistValues(object) {
var distObject = [];
var tempIndex = [];
var length = object.length;
for (var i = 0; i < length; i++) {
tempIndex.push(object[i].id);
if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
distObject.push(object[i]);
}
}
return distObject;
}

它只是给出了第一个对象。我试着映射ID并进行比较,但没有成功。

任何帮助对我都有用。

这是因为您总是将id添加到tempIndex数组,所以它总是认为当前的id是重复的。尝试:

function getDistValues(object) {
var distObject = [];
var tempIndex = [];
var length = object.length;
for (var i = 0; i < length; i++) {    
if (tempIndex.indexOf(object[i].id) === -1 || i === 0) {
tempIndex.push(object[i].id);
distObject.push(object[i]);
}
}
return distObject;
}

如果id不在集合中,则可以为id属性取一个Set并进行筛选。

var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
unique = array.filter((ids => ({ id }) => !ids.has(id) && ids.add(id))(new Set));
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }

旧JS版本的一种方法

var array = [{ id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_one', value: 'value_one', label: 'ABC' }, { id: 'id_three', value: 'value_three', label: 'ABX' }, { id: 'id_two', value: 'value_two', label: 'ABY' }, { id: 'id_four', value: 'value_four', label: 'ABD' }],
ids = {},
unique = [],
i;
for (i = 0; i < array.length; i++) {
if (ids[array[i].id]) continue;
unique.push(array[i]);
ids[array[i].id] = true;
}
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以将id存储到object中,并检查id是否已存在于object中。如果存在,那就意味着你以前拿过这个物体。如果没有,则将对象推入一个新数组。

当我们从具有恒定时间的对象进行检查时,这种方法需要O(n)时间。

var arr = [
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_three', value: 'value_three', label: 'ABX'},
{id: 'id_two', value: 'value_two', label: 'ABY'},
{id: 'id_four', value: 'value_four', label: 'ABD'}
];
function getDistValues(arr) {
	var hash = {};
var uniqueArr = [];

	for (var i = 0, l = arr.length; i < l; i++) {
	    if (hash[arr[i].id] === undefined) {
	hash[arr[i].id] = 1;
uniqueArr.push(arr[i]);
}	
}

return uniqueArr;
}
console.log(getDistValues(arr));
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以对数组使用reduce()方法,对过滤重复使用Object.values

const inputArray = [
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_one', value: 'value_one', label: 'ABC'},
{id: 'id_three', value: 'value_three', label: 'ABX'},
{id: 'id_two', value: 'value_two', label: 'ABY'},
{id: 'id_four', value: 'value_four', label: 'ABD'}
]

const filterArray = (arr) => Object.values(arr.reduce(
(acum, item) => {
acum[item.id] = item
return acum
}, 
{})
)
console.log(filterArray(inputArray))

在检查项目是否存在之前,您正在将项目添加到tempIndex数组。由于您总是添加每个项目,因此当您进行检查时,项目就已经存在了。

您必须颠倒这一点-检查项目是否存在,然后将其添加到tempIndex

var data = [
{id: "id_one", value: "value_one", label: "ABC"},
{id: "id_one", value: "value_one", label: "ABC"},
{id: "id_three", value: "value_three", label: "ABX"},
{id: "id_two", value: "value_two", label: "ABY"},
{id: "id_four", value: "value_four", label: "ABD"}
];
function getDistValues(object) {
var distObject = [];
var tempIndex = [];
var length = object.length;
for (var i = 0; i < length; i++) {
//check first
var notSeen = tempIndex.indexOf(object[i].id) === -1;

if (notSeen) {
tempIndex.push(object[i].id);
//add later
distObject.push(object[i]);
}
}
return distObject;
}
var result = getDistValues(data);
console.log(result);

为了提高效率,您还可以使用一个对象来保留重复的ID,这将消除在每个循环中对tempIndex进行另一次迭代的需要:

var data = [
{id: "id_one", value: "value_one", label: "ABC"},
{id: "id_one", value: "value_one", label: "ABC"},
{id: "id_three", value: "value_three", label: "ABX"},
{id: "id_two", value: "value_two", label: "ABY"},
{id: "id_four", value: "value_four", label: "ABD"}
];
function getDistValues(object) {
var distObject = [];
//use object
var tempIndex = {};
var length = object.length;
for (var i = 0; i < length; i++) {
var notSeen = tempIndex[object[i].id] !== true;

if (notSeen) {
//mark as visited
tempIndex[object[i].id] = true;
distObject.push(object[i]);
}
}
return distObject;
}
var result = getDistValues(data);
console.log(result);

最新更新