我有一个这样的动态对象数组:
var arr = [
{state: "FL"},
{state: "NY"},
{state: "FL"},
{gender: "Male"},
{state: "NY"},
{gender: "Female"},
{gender: "Female"},
{year: "1990"}
]
如何仅获取唯一的对象?
所需的输出是仅包含唯一对象的数组:
arr = [
{state: "FL"},
{state: "NY"},
{gender: "Male"},
{gender: "Female"},
{year: "1990"}
]
我正在尝试使用reduce进行类似的操作,但是通过这种方式,我需要知道对象键:
arr = arr.reduce((acc, curr) =>
acc.find(e => e['state'] === curr['state']) ? acc : [...acc, curr], [])
这不是重复的,因为其他问题没有使用“动态对象”来获得唯一性
答案 0 :(得分:6)
您可以对所有对象进行字符串化处理,获取唯一的JSON,然后将字符串转换回对象。
var array = [{ state: "FL" }, { state: "NY" }, { state: "FL" }, { gender: "Male" }, { state: "NY" }, { gender: "Female" }, { gender: "Female" }, { year: "1990" }],
unique = Array.from(
new Set(array.map(o => JSON.stringify(o))),
s => JSON.parse(s)
);
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果对象中有多个键,并且因为如果对象中的键的顺序不同,则建议您首先获取条目,对数组进行排序,将其字符串化为一组,然后获取新对象回来。
var array = [{ foo: 42, state: "FL" }, { state: "FL", foo: 42 }, { state: "FL" }, { state: "NY" }, { state: "FL" }, { gender: "Male" }, { state: "NY" }, { gender: "Female" }, { gender: "Female" }, { year: "1990" }],
unique = Array.from(
new Set(array.map(o => JSON.stringify(Object.entries(o).sort(([a], [b]) => a.localeCompare(b))))),
s => Object.assign({}, ...JSON.parse(s).map(([k, v]) => ({ [k]: v })))
);
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:3)
您可以reduce
到一个对象,其中对象中的每个值都是该键中的一个键(因为对象不能在键上加倍,因此可以获取唯一的值),然后将其与Object.values
来获取缩小对象中的值,如下所示:
const arr = [{state: "FL"},{state: "NY"},{state: "FL"},{gender: "Male"},{state: "NY"},{gender: "Female"},{gender: "Female"},{year: "1990"}],
reducedObj = arr.reduce((acc, obj) => {
const [key, val] = Object.entries(obj)[0];
acc[val] = {[key]: val};
return acc;
}, {});
res = Object.values(reducedObj);
console.log(res);
答案 2 :(得分:2)
想到的快速方法
JSON.stringify
将所有对象转换为字符串set
var arr = [{state: "FL"},{state: "NY"},{state: "FL"},{gender: "Male"},{state: "NY"},{gender: "Female"}, {gender: "Female"},{year: "1990"}
]
const stringArr = arr.map(str => JSON.stringify(str));
const uniqueStrs = [ ...new Set(stringArr)] // removes duplicates
const result = uniqueStrs.map(str => JSON.parse(str));
console.log(result);
答案 3 :(得分:1)
我也知道,我也知道...但是我的回答更加简洁。
[...new Set(arr.map(JSON.stringify))].map(JSON.parse);
使用JSON.stringify
通常会有一些警告,即根据规范,您不能依赖键的顺序来保持一致。如果只有一个键,这将永远不会成为问题。如果每个对象都是通过按相同的顺序添加键来构造的,那么这也不会有问题,因为大多数实现会保留键添加的顺序。
答案 4 :(得分:1)
此性能将比使用JSON.parse和stringify的任何方法都要好。
var arr = [
{state: "FL"},
{state: "NY"},
{state: "FL"},
{gender: "Male"},
{state: "NY"},
{gender: "Female"},
{gender: "Female"},
{year: "1990"}
];
const unique = arr => arr.filter((item, index) => !arr.some((i, idx) => idx > index && Object.getOwnPropertyNames(item).every(property => i[property] === item[property])));
console.log(unique(arr));
或使用reduce而不是您尝试过的过滤器
var arr = [
{state: "FL"},
{state: "NY"},
{state: "FL"},
{gender: "Male"},
{state: "NY"},
{gender: "Female"},
{gender: "Female"},
{year: "1990"}
];
const unique = arr => arr.reduce((results, item) => {
if (!results.some(i => Object.getOwnPropertyNames(item).every(property => i[property] === item[property]))) {
results.push(item);
}
return results;
}, []);
console.log(unique(arr));
答案 5 :(得分:0)
这应该有效
const arr = [
{ state: 'FL' },
{ state: 'NY' },
{ state: 'FL' },
{ gender: 'Male' },
{ state: 'NY' },
{ gender: 'Female' },
{ gender: 'Female' },
{ year: '1990' },
];
arr.reduce((array, obj) => {
for (const target of array) {
if (JSON.stringify(target) === JSON.stringify(obj)) {
return array;
}
return [...array, obj];
}
}, []);
答案 6 :(得分:0)
很多方法可以做到这一点:这是两种:
reduce
for loop
var arr = [
{state: "FL"},
{state: "NY"},
{state: "FL"},
{gender: "Male"},
{state: "NY"},
{gender: "Female"},
{gender: "Female"},
{year: "1990"}
]
//two solutions
//1. reduce and some
let arr1 = arr.reduce( (acc, currentValue) => {
const key = Object.keys(currentValue)[0]; //we only have one property!
const inArr = acc.some((element) => {return element[key] == currentValue[key]});
if (!inArr)
{
acc.push(currentValue);
}
return acc;
},[]);
console.log(arr1);
//2. for loop
//you can still do a for loop (Quick):
const shadow = [];
const iMax= arr.length;
for (let i = 0; i < iMax; i++)
{
const key = Object.keys(arr[i])[0]; //we only have one property!
//check if value is not in shadow array
if (shadow.indexOf(arr[i][key]) == -1)
{
arr.push(arr[i]);
shadow.push(arr[i][key]);
}
}
//splice off the original values
arr.splice(0, iMax);
console.log(arr);
答案 7 :(得分:0)
使用filter
方法:
var arr = [
{state: "FL"}, {state: "NY"}, {state: "FL"}, {gender: "Male"},
{state: "NY"}, {gender: "Female"}, {gender: "Female"}, {year: "1990"}
]
var len = arr.length ;
var result = [] ;
var result = arr.filter( (cur, inx) => {
var same = 0 ;
var curKey = Object.keys(cur)[0] ;
for ( var i = inx + 1; i < len; i++ )
if ( cur[curKey] === arr[i][curKey] ) { same++; break; }
return !same;
})
console.log( result ) ;