我创建了一个对象数组,如下所示:
[
{
"lat": 12.123,
"lng": 13.213,
"city": "New York"
},
{
"lat": 3.123,
"lng": 2.213,
"city": "New York"
},
{
"lat": 1.513,
"lng": 1.113,
"city": "London"
}
]
我正在尝试创建一个新数组,将
places
过滤为仅包含不具有相同 city
属性的对象(纬度/经度重复是可以的)。是否有内置的 JS 或 Jquery 函数可以实现此目的?
我可能会在过滤过程中使用标志对象(编辑:我不会了,请参阅关于 ES2015 的答案末尾的注释
Set
),如下所示:
var flags = {};
var newPlaces = places.filter(function(entry) {
if (flags[entry.city]) {
return false;
}
flags[entry.city] = true;
return true;
});
Array#filter
,它是可以填充的 ES5 附加项之一(搜索“es5 shim”以获取多个选项)。
不用
filter
也可以做到,当然,只是比较冗长一点:
var flags = {};
var newPlaces = [];
var index;
for (index = 0; index < places.length; ++index) {
if (!flags[entry.city]) {
flags[entry.city] = true;
newPlaces.push(entry);
}
});
以上两者都假设应保留具有给定城市的first对象,并丢弃所有其他对象。
注意:正如 user2736012 在下面指出的那样,对于名称恰好与
if (flags[entry.city])
上存在的属性(例如 Object.prototype
)相同的城市,我的测试 toString
将成立。在这种情况下可能性很小,但有四种方法可以避免这种可能性:
(我通常首选的解决方案)创建没有原型的对象:
var flags = Object.create(null);
。这是ES5的一个特性。请注意,对于像 IE8 这样的过时浏览器,不能对此进行填充(当参数值为 Object.create
时,null
的单参数版本可以是 except)。
使用
hasOwnProperty
进行测试,例如if (flags.hasOwnProperty(entry.city))
添加您知道任何
Object.prototype
属性都不存在的前缀,例如 xx
:
var key = "xx" + entry.city;
if (flags[key]) {
// ...
}
flags[key] = true;
从 ES2015 开始,您可以使用
Set
代替:
const flags = new Set();
const newPlaces = places.filter(entry => {
if (flags.has(entry.city)) {
return false;
}
flags.add(entry.city);
return true;
});
最短,但不是最佳性能(请参阅下面的更新)es6 的解决方案:
function unique(array, propertyName) {
return array.filter((e, i) => array.findIndex(a => a[propertyName] === e[propertyName]) === i);
}
您可以通过仅包含具有尚未添加到 filter
的属性值的元素来使用
Set
(之后应将其添加到
Set
)。这可以使用逻辑与运算符 (Set
) 在一行中完成。使用这种数据结构具有次线性查找时间的优点(通常&&
)。下面是一个通用函数,用于根据对象数组 (O(1)
) 中的特定属性 (prop
) 获取唯一的对象数组。请注意,在重复的情况下,仅保留第一个具有属性值的对象。
arr
演示:
const getUniqueBy = (arr, prop) => {
const set = new Set;
return arr.filter(o => !set.has(o[prop]) && set.add(o[prop]));
};
https://github.com/lodash/lodash/blob/4.13.1/lodash.js#L7711
var places = [{
lat: 12.123,
lng: 13.213,
city: 'New York'
}, {
lat: 3.123,
lng: 2.213,
city: 'New York'
}, {
lat: 3.123,
lng: 4.123,
city: 'Some City'
}];
const getUniqueBy = (arr, prop) => {
const set = new Set;
return arr.filter(o => !set.has(o[prop]) && set.add(o[prop]));
};
console.log(getUniqueBy(places, 'city'));
我对 @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.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);
}
}
}
或
places.uniqueCity();
通过上述内容,您可以按对象中的任何字段对数组进行排序,
即使某些对象不存在这些字段。
或
Array.prototype.uniqueObjectArray = function(field) {
var processed = [];
for (var i=this.length-1; i>=0; i--) {
if (this[i].hasOwnProperty(field)) {
if (processed.indexOf(this[i][field])<0) {
processed.push(this[i][field]);
} else {
this.splice(i, 1);
}
}
}
}
places.uniqueObjectArray('city');
您可以使用地图,以便具有相同键属性(在您的情况下为“城市”)的条目仅出现一次
您可以将其粘贴到控制台上以查看其工作情况。 它应该适用于所呈现的场景和其他一些场景。
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' }
])
我们可以使用 JavaScriptMap
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 cityMap = new Map();
places.forEach(p=> cityMap.set(p.city, p));
console.log([...cityMap.values()]);
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);
var unique = {}
for (var i = 0; i < places.length; i++) {
var place = places[i];
unique[place.city] = place;
}
for (var name in unique) {
var place = unique[name];
console.log(place);
}
在简单的
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;
}
Javascript
数组列表中删除重复的城市是
places
基于上面https://stackoverflow.com/a/18773857/49564
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));
这个帖子可能很旧,但我想我应该分享它。它基于纯 JavaScript,并根据指定的属性删除重复对象。