我需要根据以下2个属性从数组中找到唯一对象。当" class"和"票价"匹配,我需要提取唯一值并将它们放在结果数组中。
来源:
var arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
预期结果:
var result = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
我查看了SO,并且能够找到基于一个属性(Create array of unique objects by property)过滤的答案,但无法找到基于2个属性可以做的事情。
答案 0 :(得分:11)
您可以为哈希表构建一个组合键,过滤给定数组。
var arr = [{ class: "second", fare: "a" }, { class: "second", fare: "b" }, { class: "first", fare: "a" }, { class: "first", fare: "a" }, { class: "second", fare: "a" }, { class: "first", fare: "c" }],
result = arr.filter(function (a) {
var key = a.class + '|' + a.fare;
if (!this[key]) {
this[key] = true;
return true;
}
}, Object.create(null));
console.log(result);
答案 1 :(得分:2)
使用组合键和地图
const array = [
{ class: "second", fare: "a" },
{ class: "second", fare: "b" },
{ class: "first", fare: "a" },
{ class: "first", fare: "a" },
{ class: "second", fare: "a" },
{ class: "first", fare: "c" }
];
console.log(unique(array, ['class', 'fare']));
function unique(arr, keyProps) {
const kvArray = arr.map(entry => {
const key = keyProps.map(k => entry[k]).join('|');
return [key, entry];
});
const map = new Map(kvArray);
return Array.from(map.values());
}

答案 2 :(得分:1)
解决上述问题的简便方法,尽管它是一个非常老的线程,并且也许将来会对某人有所帮助。
const array = [
{ class: "second", fare: "a" },
{ class: "second", fare: "b" },
{ class: "first", fare: "a" },
{ class: "first", fare: "a" },
{ class: "second", fare: "a" },
{ class: "first", fare: "c" }
];
const uniqueObjects = new Set();
array.forEach(arr => uniqueObjects.add(JSON.stringify(arr)));
console.log(uniqueObjects.entries())
答案 3 :(得分:1)
基于对象字段的任意数组提取对象唯一数组的另一种方法,经过性能测试:
在性能上总是最好的,使用递归函数
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arrInp = [{}], objTmp={}, arrTmp=[]) => {
if (arrInp.length > 0) {
const lastItem = arrInp[arrInp.length -1]
const propStr = props.reduce((res, item) => (`${res}${lastItem[item]}`), '')
if (!objTmp[propStr]) {
objTmp[propStr] = true
arrTmp=[...arrTmp, lastItem]
}
arrInp.pop()
return getUniqArrBy(props, arrInp, objTmp, arrTmp)
}
return arrTmp
}
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class: "first", fare: "c"},
{class: "second", fare: "a"},
{class: "first", fare: "a"},
{class: "second", fare: "b"},
]
*/
在性能方面落后于第一名
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arrInp = [{}]) => {
const objKey = {}
return arrInp.reduce((res, item) => {
const valStr = props.reduce((res, prop) => `${res}${item[prop]}`, '')
if(objKey[valStr]) return res
objKey[valStr] = item
return [...res, item]
}, [])
}
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
*/
在表现上接近拳头两个
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arr = [{}]) => arr.filter((e, i) =>
arr.findIndex(a => {
let aKey = '', eKey = ''
props.forEach(prop => (aKey = `${aKey}${a[prop]}`, eKey = `${eKey}${e[prop]}`))
return aKey === eKey
}) === i)
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
*/
在Firefox中运行迅速,在Chrome和Edge中-并非如此,简而言之
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arrInp = [{}]) => {
return Object.values(arrInp.reduce((res, item) => {
const keyComb = props.reduce((res, prop) => `${res}${item[prop]}`, '')
return { ...res, [keyComb]: item }
}, []))
}
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
*/
缩写,但通常比第一个慢5-8%
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arr = [{}]) => arr.filter((e, i) =>
arr.findIndex(a => props.reduce((res, prop) => `${res}${a[prop]}`, '') ===
props.reduce((res, prop) => `${res}${e[prop]}`, '')) === i)
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
*/
在不同的浏览器中,平均速度比第一个慢9-18%
const arr = [{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "a"},
{class:"second", fare: "a"},
{class:"first", fare: "c"}
]
const getUniqArrBy = (props = [], arrInp = [{}]) => {
const objKey = arrInp.reduce((res, item) => {
const valStr = props.reduce((res, prop) => `${res}${item[prop]}`, '')
return {...res, [valStr]: item }
}, {})
return Object.keys(objKey).map(item => objKey[item])
}
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
/*
[
{class:"second", fare: "a"},
{class:"second", fare: "b"},
{class:"first", fare: "a"},
{class:"first", fare: "c"}
]
*/
答案 4 :(得分:1)
根据对象字段的任意数组提取对象的唯一数组的另一种形式:
const arr = [
{ class: 'second', fare: 'a', weight: 12 },
{ class: 'second', fare: 'b', weight: 10 },
{ class: 'first', fare: 'a', weight: 15 },
{ class: 'first', fare: 'a', weight: 17 },
{ class: 'second', fare: 'a', weight: 12 },
{ class: 'first', fare: 'c', weight: 30 },
{ class: 'second', fare: 'b', weight: 22 },
]
const getUniqArrBy = (props = [], arrInp = [{}]) => {
const obj = {}
let result = []
arrInp.forEach((item, index) => {
let key = ''
props.forEach(prop => (key += item[prop]))
obj[key] = index
})
const keys = Object.keys(obj)
keys.forEach(key => (result = [...result, arrInp[obj[key]]]))
return result
}
const uniq = getUniqArrBy(['class', 'fare'], arr)
console.info({ uniq })
答案 5 :(得分:0)
您可以使用forEach
循环和filter
或find
数组属性来查找元素是否存在于数组中
var arr = [{
class: "second",
fare: "a"
}, {
class: "second",
fare: "b"
}, {
class: "first",
fare: "a"
}, {
class: "first",
fare: "a"
}, {
class: "second",
fare: "a"
}, {
class: "first",
fare: "c"
}]
var _unArray = []; // new array without duplicate
arr.forEach(function(item) { // loop through array which contain duplicate
// if item is not found in _unArray it will return empty array
var isPresent = _unArray.filter(function(elem) {
return elem.class === item.class && elem.fare === item.fare
})
if (isPresent.length == 0) {
_unArray.push(item)
}
})
console.log(_unArray)
答案 6 :(得分:0)
function unique(arr, keyProps) {
const kvArray = arr.map(entry => { // entry = {class: "second", fare: "a"}
// keyProps = ["class", "fare"]
// k="class"; entry[k]="second";
// k="fare"; entry[k]="a"
// keyProps.map(k => entry[k])=["second","a"];
// .join("|")="second|a";
const key = keyProps.map(k => entry[k]).join('|'); // key = "second|a"
return [key, entry]; // ["second|a",{"class":"second","fare":"a"}]
});
// kvArray = [["second|a",{"class":"second","fare":"a"}],["second|b",
// {"class":"second","fare":"b"}],["first|a",{"class":"first","fare":"a"}],
// ["first|a",{"class":"first","fare":"a"}],["second|a",
// {"class":"second","fare":"a"}],["first|c",{"class":"first","fare":"c"}]]
const map = new Map(kvArray); // this will remove duplicate entry with same key.
return Array.from(map.values()); // convert back to array from all entry's value
}
答案 7 :(得分:0)
与大多数答案一样,将其转换为键,键为值的串联,然后返回数组。此人使用reduce
。
const array = [
{ class: "second", fare: "a" },
{ class: "second", fare: "b" },
{ class: "first", fare: "a" },
{ class: "first", fare: "a" },
{ class: "second", fare: "a" },
{ class: "first", fare: "c" }
];
console.log(unique(array, ['class', 'fare']));
function unique(arr, keyProps) {
return Object.values(arr.reduce((uniqueMap, entry) => {
const key = keyProps.map(k => entry[k]).join('|');
if (!(key in uniqueMap)) uniqueMap[key] = entry;
return uniqueMap;
}, {}));
}
答案 8 :(得分:0)
嘿,您可以使用此方法
const unique = (arr, props = []) => [...new Map(arr.map(entry => [props.map(k => entry[k]).join('|'), entry])).values()];
const array = [
{
class: 'second',
fare: 'a',
},
{
class: 'second',
fare: 'b',
},
{
class: 'first',
fare: 'a',
},
{
class: 'first',
fare: 'a',
},
{
class: 'second',
fare: 'a',
},
{
class: 'first',
fare: 'c',
},
];
const newArr = unique(array, ['class', 'fare']);
console.log(newArr) // [{ class: 'second', fare: 'a' }, { class: 'second', fare: 'b' }, { class: 'first', fare: 'a' }, { class: 'first', fare: 'c' }]