Javascript 按属性创建唯一对象的数组
我创建了一个对象数组,如下所示:Javascript 按属性创建唯一对象的数组,javascript,jquery,filter,Javascript,Jquery,Filter,我创建了一个对象数组,如下所示: [ { “lat”:12.123, “液化天然气”:13.213, “城市”:“纽约” }, { “lat”:3.123, “液化天然气”:2.213, “城市”:“纽约” }, { “lat”:1.513, “液化天然气”:1.113, “城市”:“伦敦” } ] 我正在尝试创建一个新数组,该数组将过滤位置,以仅包含不具有相同城市属性的对象(可以使用lat/lng副本)。是否有内置的JS或Jquery函数来实现这一点?我可能会在过滤过程中使用flags对象,
[
{
“lat”:12.123,
“液化天然气”:13.213,
“城市”:“纽约”
},
{
“lat”:3.123,
“液化天然气”:2.213,
“城市”:“纽约”
},
{
“lat”:1.513,
“液化天然气”:1.113,
“城市”:“伦敦”
}
]
我正在尝试创建一个新数组,该数组将过滤
位置
,以仅包含不具有相同城市
属性的对象(可以使用lat/lng副本)。是否有内置的JS或Jquery函数来实现这一点?我可能会在过滤过程中使用flags对象,如下所示:
var flags = {};
var newPlaces = places.filter(function(entry) {
if (flags[entry.city]) {
return false;
}
flags[entry.city] = true;
return true;
});
它使用ECMAScript5(ES5),这是可以填充的ES5添加项之一(搜索“ES5填充”以获得多个选项)
您可以在不使用过滤器的情况下执行此操作,当然,它只是有点冗长:
var flags = {};
var newPlaces = [];
var index;
for (index = 0; index < places.length; ++index) {
if (!flags[entry.city]) {
flags[entry.city] = true;
newPlaces.push(entry);
}
});
从ES2015开始,您可以使用集合
:
const flags = new Set();
const newPlaces = places.filter(entry => {
if (flags.has(entry.city)) {
return false;
}
flags.add(entry.city);
return true;
});
正如注释中指出的,您可以使用对象作为映射,这样可以避免重复,然后可以枚举对象的属性
工作小提琴:
var places=[];
变量a={};
a、 lat=12.123;
a、 液化天然气=13.213;
a、 城市=“纽约”;
地点:推(a);
var b={};
b、 lat=3.123;
b、 液化天然气=2.213;
b、 城市=“纽约”;
地点:推(b);
var unique={}
对于(变量i=0;i
我的建议:
Array.prototype.uniqueCity = function() {
var processed = [];
for (var i=this.length-1; i>=0; i--){
if (processed.indexOf(this[i].city)<0) {
processed.push(this[i].city);
} else {
this.splice(i, 1);
}
}
}
或
Array.prototype.uniqueObjectArray=函数(字段){
var处理=[];
对于(var i=this.length-1;i>=0;i--){
if(此[i].hasOwnProperty(字段)){
if(processed.indexOf(此[i][field])=0;i--{
if(processed.indexOf(array[i].city)
这个线程可能很旧,但我认为我应该共享它。它基于纯JavaScript,并根据指定的属性删除重复的对象
function removeDuplicates(originalArray, properties) {
var newArray = [];
var index = 0;
var lookupObject = {};
var totalProperties = properties.length;
for (var i = 0; i < originalArray.length; i++) {
var exists = false;
for (var a = 0; a < newArray.length; a++) {
var propsFound = 0;
for (var b = 0; b < totalProperties; b++) {
if (originalArray[i][properties[b]] == newArray[a][properties[b]]) {
propsFound++;
}
}
//If there is a match then break the for loop
if (propsFound == totalProperties) {
exists = true;
break;
}
} //End of New Array
if (!exists) {
newArray[index] = originalArray[i];
index++;
}
} //End of originalArray
return newArray;
}
函数移除的副本(原始阵列、属性){
var newArray=[];
var指数=0;
var lookupObject={};
var totalProperties=properties.length;
对于(变量i=0;i
您可以查看适用于es6的最短但不是最佳性能(请参阅下面的更新)的小提琴解决方案:
function unique(array, propertyName) {
return array.filter((e, i) => array.findIndex(a => a[propertyName] === e[propertyName]) === i);
}
性能:我对@IgorL解决方案进行了一些扩展,但对原型进行了扩展,并为其提供了一个选择器函数,而不是一个属性,使其更加灵活:
Array.prototype.unique = function(selector) {
return this.filter((e, i) => this.findIndex((a) => {
if (selector) {
return selector(a) === selector(e);
}
return a === e;
}) === i);
};
用法:
// with no param it uses strict equals (===) against the object
let primArr = ['one','one','two','three','one']
primArr.unique() // ['one','two','three']
let a = {foo:123}
let b = {foo:123}
let fooArr = [a,a,b]
fooArr.unique() //[a,b]
// alternatively, you can pass a selector function
fooArr.unique(item=>item.foo) //[{foo:123}] (first "unique" item returned)
这肯定不是最有效的方法,但只要选择器简单且阵列不庞大,它就可以正常工作
打字
Array.prototype.unique=函数(this:T[],选择器?:(item:T)=>对象):T[]{
返回this.filter((e,i)=>this.findIndex((a)=>{
如果(选择器){
返回选择器(a)==选择器(e);
}
返回a==e;
})==i);
};
您可以使用地图,使具有相同密钥属性的条目(在您的示例中为“城市”)只显示一次
module.exports = (array, prop) => {
const keyValueArray = array.map(entry => [entry[prop], entry]);
const map = new Map(keyValueArray);
return Array.from(map.values());
};
有关贴图和阵列对象的详细信息
另一个选项:
const uniqueBy = prop => list => {
const uniques = {}
return list.reduce(
(result, item) => {
if (uniques[item[prop]]) return result
uniques[item[prop]] = item
return [...result, item]
},
[],
)
}
const uniqueById = uniqueBy('id')
uniqueById([
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
{ id: 1, name: 'one' },
{ id: 3, name: 'three' }
])
您可以将其粘贴到控制台上以查看其工作情况。
它应该适用于所介绍的场景和其他一些场景。在简单的Javascript
中,从位置删除重复城市的代码是
var places = [{ 'lat': 12.123, 'lng': 13.213, 'city': "New York"},
{ 'lat': 3.123, 'lng': 2.213, 'city': "New York"},
{ 'lat': 43.123, 'lng': 12.213, 'city': "London"}];
var unique = [];
var tempArr = [];
places.forEach((value, index) => {
if (unique.indexOf(value.city) === -1) {
unique.push(value.city);
} else {
tempArr.push(index);
}
});
tempArr.reverse();
tempArr.forEach(ele => {
places.splice(ele, 1);
});
console.log(places);
基于上述内容的通用类型脚本答案:
导出函数isDistinct(映射器:(值:T)=>string):(值:T)=>boolean{
常量键:{[index:string]:boolean}={};
返回(输入:T)=>{
常量键=映射器(条目);
如果(键[键]!==未定义){
返回false;
}
返回键[键]=真;
};
}
//用法示例:
const items=[{id:1},{id:2},{id:3},{id:1}];
const unique=items.filter(isDistinct(i=>i.id));
我想你想要这个
注意:不需要库
let数组=[{id:1},{id:2},{id:3}];
函数addUniqeObj(数据){
设指数=-1;
for(设i=0,i-1){
数组[索引]=数据;
}否则{
array.push(数据)
}
}
我们可以使用JavaScript通过任何属性创建唯一对象的列表
例如:
var places=[{'lat':12.123,'lng':13.213,'city':“newyork”},
{'lat':3.123,'lng':2.213,'city':“newyork”},
{'lat':43.123,'lng':12.213,'city':“London”}];
var cityMap=新映射();
places.forEach(p=>cityMap.set(p.city,p));
console.log([…cityMap.values()]);
该方法的另一个变体:
const重复数据示例=[
{id:1,c:'无论如何'},
{id:1,c:'1whatever'},
{id:2,c:'2whatever'},
{id:2,c:'2whatever'},
{id:3,c:'2whatever'},
]
const getUniqueBy=(道具,列表)=>{
const objUniq=list.reduce((res,item)=>({…res,[item[prop]]:item}),{})
返回Object.keys(objUniq.map)(item=>objUniq[item])
}
const uniq=getUniqueBy('id',示例)
console.info('info',{uniq})
/* [
{id:1,c:'无论如何'},
{id:2,c:'2whatever'},
{id:3,c:'2whatever'},
]*/
您可以通过只包含属性值尚未添加到集中的元素来使用
var places = [];
var a = {};
a.lat = 12.123;
a.lng = 13.213;
a.city = "New York";
places.push(a);
var b = {};
b.lat = 3.123;
b.lng = 2.213;
b.city = "New York";
places.push(b);
getUniqAR(places,'city'); //Return Uniq Array by property
function getUniqAR(Data,filter){
var uniar =[];
Data.forEach(function(item,ind,arr){
var dupi=false;
if(!uniar.length) uniar.push(item) //push first obj into uniq array
uniar.forEach(function(item2, ind2,arr){
if(item2[filter] == item[filter]){ //check each obj prop of uniq array
dupi=true; //if values are same put duplicate is true
}
})
if(!dupi){ uniar.push(item)} //if no duplicate insert to uniq
})
console.log(uniar)
return uniar;
}
function unique(array, propertyName) {
return array.filter((e, i) => array.findIndex(a => a[propertyName] === e[propertyName]) === i);
}
Array.prototype.unique = function(selector) {
return this.filter((e, i) => this.findIndex((a) => {
if (selector) {
return selector(a) === selector(e);
}
return a === e;
}) === i);
};
// with no param it uses strict equals (===) against the object
let primArr = ['one','one','two','three','one']
primArr.unique() // ['one','two','three']
let a = {foo:123}
let b = {foo:123}
let fooArr = [a,a,b]
fooArr.unique() //[a,b]
// alternatively, you can pass a selector function
fooArr.unique(item=>item.foo) //[{foo:123}] (first "unique" item returned)
Array.prototype.unique = function<T>(this: T[], selector?: (item: T) => object): T[] {
return this.filter((e, i) => this.findIndex((a) => {
if (selector) {
return selector(a) === selector(e);
}
return a === e;
}) === i);
};
module.exports = (array, prop) => {
const keyValueArray = array.map(entry => [entry[prop], entry]);
const map = new Map(keyValueArray);
return Array.from(map.values());
};
const uniqueBy = prop => list => {
const uniques = {}
return list.reduce(
(result, item) => {
if (uniques[item[prop]]) return result
uniques[item[prop]] = item
return [...result, item]
},
[],
)
}
const uniqueById = uniqueBy('id')
uniqueById([
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
{ id: 1, name: 'one' },
{ id: 3, name: 'three' }
])
var places = [{ 'lat': 12.123, 'lng': 13.213, 'city': "New York"},
{ 'lat': 3.123, 'lng': 2.213, 'city': "New York"},
{ 'lat': 43.123, 'lng': 12.213, 'city': "London"}];
var unique = [];
var tempArr = [];
places.forEach((value, index) => {
if (unique.indexOf(value.city) === -1) {
unique.push(value.city);
} else {
tempArr.push(index);
}
});
tempArr.reverse();
tempArr.forEach(ele => {
places.splice(ele, 1);
});
console.log(places);
export function isDistinct<T>(mapper: (value: T) => string): (value: T) => boolean {
const keys: { [index: string]: boolean } = {};
return (entry: T) => {
const key = mapper(entry);
if (keys[key] !== undefined) {
return false;
}
return keys[key] = true;
};
}
// Usage example:
const items = [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 1 } ];
const unique = items.filter(isDistinct(i => i.id));
let array = [{ id: 1}, {id: 2}, {id: 3}];
function addUniqeObj(data) {
let index = -1;
for(let i = 0, i < array.length; i++) {
if(array[i].id === data.id) {
index = i;
}
}
if(index > -1) {
array[index] = data;
} else {
array.push(data)
}
}
const getUniqueBy = (arr, prop) => {
const set = new Set;
return arr.filter(o => !set.has(o[prop]) && set.add(o[prop]));
};