我创建了一个像这样的对象数组:
[
{
"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属性的对象(lat/lng副本是可以的)。是否有内置的JS或Jquery函数来实现这一点?
发布于 2013-09-12 20:34:28
在过滤过程中,我可能会使用一个标志对象(编辑:我不会再使用了,请看答案末尾关于use 2015的Set__的注释),如下所示:
var flags = {};
var newPlaces = places.filter(function(entry) {
if (flags[entry.city]) {
return false;
}
flags[entry.city] = true;
return true;
});它使用Array#filter (来自ECMAScript5 ( ES5 ) ),这是可以抖动的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);
}
});上述两种假设都假设应该保留具有给定城市的第一个对象,而所有其他对象都应被丢弃。
注意:正如user2736012在下面指出的那样,我的测试if (flags[entry.city])对于具有与Object.prototype上存在的属性(如toString )相同的名称的城市来说是正确的。在这种情况下不太可能,但有四种方法可以避免这种可能性:
var flags = Object.create(null);。这是ES5的一个特性。请注意,对于IE8这样的过时浏览器( Object.create的单参数版本可以是null,除非该参数的值是null),这是不可能的。hasOwnProperty,例如if (flags.hasOwnProperty(entry.city))Object.prototype属性(如xx)添加一个前缀,您知道该前缀不存在:
var key = "xx“+ entry.city;if (标记键){ // .}标记键= true;Set来代替:
const标志=新集();const newPlaces =places.filter(条目=> { if (flags.has(entry.city){返回false;} flags.add(entry.city);返回true;};发布于 2020-08-14 19:28:40
您可以使用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]));
};演示:
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'));
发布于 2016-07-20 04:27:01
https://lodash.com/docs#uniqBy
https://github.com/lodash/lodash/blob/4.13.1/lodash.js#L7711
/**
* This method is like `_.uniq` except that it accepts `iteratee` which is
* invoked for each element in `array` to generate the criterion by which
* uniqueness is computed. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {Array|Function|Object|string} [iteratee=_.identity]
* The iteratee invoked per element.
* @returns {Array} Returns the new duplicate free array.
* @example
*
* _.uniqBy([2.1, 1.2, 2.3], Math.floor);
* // => [2.1, 1.2]
*
* // The `_.property` iteratee shorthand.
* _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }, { 'x': 2 }]
*/https://stackoverflow.com/questions/18773778
复制相似问题