按属性创建唯一对象数组 [英] Create array of unique objects by property
问题描述
我创建了一个像这样的对象数组:
var places = [];
var a = {};
a.lat = 12.123;
a.lng = 13.213;
a.city =纽约;
places.push(a);
var b = {};
b.lat = 3.123;
b.lng = 2.213;
b.city =纽约;
places.push(b);
...
我试图创建一个新的数组过滤地方只包含不具有相同城市属性的对象(纬度/经度重复是好的)。有没有建立在JS或JQuery的功能来实现这一目标?
我可能会在过滤期间使用一个标记对象,如下所示:
var flags = {};
var newPlaces = places.filter(function(entry){
if(flags [entry.city]){
return false;
}
flags [entry。 city] = true;
返回true;
});
使用 ,这是ES5添加之一(可以搜索es5 shim获得多个选项)。
您可以在
var flags = {};
var newPlaces = [];
var index;
for(index = 0; index< places.length; ++ index){
if(!flags [entry.city]){
flags [entry.city] = true;
newPlaces.push(entry);
}
});
以上两个假设第一个对象与给定的城市应该是保存,所有其他丢弃。
注意:在user2736012指出下面,我的测试 if (flags [entry.city])
对于名称与 Object.prototype
等属性相同的城市将是真实的作为 toString
。在这种情况下不太可能,但有四种方法可以避免这种可能性:
(我通常喜欢的解决方案)创建对象没有原型: var flags = Object.create(null);
。这是ES5的一个功能。请注意,对于像IE8这样的过时浏览器来说,这个参数的值是,当然这个参数的值是 code> null )。
hasOwnProperty
测试,例如 if(flags.hasOwnProperty(entry.city))
对于任何 Object.prototype
属性,例如 xx
:
var key =xx+ entry.city;
if(flags [key]){
// ...
}
flags [key] = true;
从ES2015开始,您可以使用 Set < c $ c>代替:
const flags = new Set();
const newPlaces = places.filter(entry => {
if(flags.has(entry.city)){
return false;
}
标志。 add(entry.city);
return true;
});
I created an array of objects like so:
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);
...
I'm trying to create a new array that filters the places to only contains objects that don't have the same city property (lat/lng duplicates are ok). Is there a built in JS or Jquery function to achieve this?
I'd probably use a flags object during the filtering, like this:
var flags = {};
var newPlaces = places.filter(function(entry) {
if (flags[entry.city]) {
return false;
}
flags[entry.city] = true;
return true;
});
That uses Array#filter
from ECMAScript5 (ES5), which is one of the ES5 additions that can be shimmed (search for "es5 shim" for several options).
You can do it without filter
, of course, it's just a bit more verbose:
var flags = {};
var newPlaces = [];
var index;
for (index = 0; index < places.length; ++index) {
if (!flags[entry.city]) {
flags[entry.city] = true;
newPlaces.push(entry);
}
});
Both of the above assume the first object with a given city should be kept, and all other discarded.
Note: As user2736012 points out below, my test if (flags[entry.city])
will be true for cities with names that happen to be the same as properties that exist on Object.prototype
such as toString
. Very unlikely in this case, but there are four ways to avoid the possibility:
(My usual preferred solution) Create the object without a prototype:
var flags = Object.create(null);
. This is a feature of ES5. Note that this cannot be shimmed for obsolete browsers like IE8 (the single-argument version ofObject.create
can be except when that argument's value isnull
).Use
hasOwnProperty
for the test, e.g.if (flags.hasOwnProperty(entry.city))
Put a prefix on that you know doesn't exist for any
Object.prototype
property, such asxx
:var key = "xx" + entry.city; if (flags[key]) { // ... } flags[key] = true;
As of ES2015, you could use a
Set
instead:const flags = new Set(); const newPlaces = places.filter(entry => { if (flags.has(entry.city)) { return false; } flags.add(entry.city); return true; });
这篇关于按属性创建唯一对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!