过滤具有重复值的元素数组,在另一个属性中选择具有特定值的元素

时间:2018-02-21 09:09:15

标签: javascript

情况是我有一些对象的数组,我们称之为事件。

每个事件都有“name”和“type”属性。我希望通过保留具有特定“类型”的事件来过滤掉具有相同“名称”的事件。我不想过滤掉没有重复的事件! 基本上,这个概念最终会得到一个明确命名的事件列表,其中只要存在重复的NAME,具有给定TYPE的事件就会保留在数组中。

我该怎么做?我知道我可以使用events.filter()来删除重复项,但是如何根据另一列选择?

样品:

var eventArray = [{name:"test",type:"building"}, {name:"test",type:"learning"}, 
                  {name:"audit", type:"preparing"}, {name:"audit", type:"learning"},
{name:"bla",type:"blue"}];

我的目标是过滤掉具有重复名称的事件,但在此过滤期间,要保留类型为“learning”的事件。所以最终的结果应该是:

var eventArray = [{name:"test",type:"learning"},  {name:"audit", type:"learning"},{name:"bla",type:"blue"}];

谢谢!

2 个答案:

答案 0 :(得分:1)

这是第一个版本,第一个函数(duplicateNames)将返回事件数组中重复名称值的数组。 removeDuplicated方法检查名称是否重复,如果是,它只会获取具有首选类型的名称,如果它没有重复,则只需添加它。

但是有一个缺点,如果你有一个重复的名字,但没有一个对象属于首选类型,它们将被忽略,例如:

var eventArray = [{name: 'test', type: 'hello'}, {name: 'test', type: 'hello2'}];

此外,如果类型也重复,您将获得两个条目,这是您期望的吗?



const eventArray = [
	{name:"test5",type:"building"},
	{name:"test5",type:"building"},
	{name:"test",type:"building"},
	{name:"test",type:"learning"},
	{name:"audit", type:"preparing"},
	{name:"audit", type:"learning"}
];

function uniq(array) {
	return array
		.map(item => JSON.stringify(item))
		.filter((item, index, arr) => arr.indexOf(item) === index)
		.map(item => JSON.parse(item));
}

function duplicatedNames(array) {
	const names = array.map(item => item.name);
	return names
		.filter((name, index) => names.indexOf(name) !== index);
}


function removeDuplicates(array, preferenceType) {
	const unique = uniq(array);
	const duplicated = duplicatedNames(unique);
	const result = [];

	for (const item of unique) {
		if (duplicated.indexOf(item.name) >= 0 && item.type === preferenceType) {
			result.push(item);
		} else if (duplicated.indexOf(item.name) < 0) {
			result.push(item);
		}
	}

	return result;
}

console.log(removeDuplicates(eventArray, 'learning'));
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用array#filter根据条件过滤掉您的阵列。然后,使用array#reduce根据name对结果进行唯一分组,并将其存储在对象中。然后使用Object.values()从该对象中提取出所有值。

&#13;
&#13;
var eventArray = [{name:"test",type:"building"}, {name:"test",type:"learning"},{name:"audit", type:"preparing"}, {name:"audit", type:"learning"}, {name:"audit", type:"learning"}, {name:"audit", type:"learning"}],
    result = Object.values(eventArray.filter(({type}) => type === 'learning').reduce((r,o) => {
      r[o.name] = o;
      return r;
    },{}));
console.log(result);
&#13;
&#13;
&#13;