首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按属性创建唯一对象数组

按属性创建唯一对象数组
EN

Stack Overflow用户
提问于 2013-09-12 20:29:06
回答 16查看 89.7K关注 0票数 61

我创建了一个像这样的对象数组:

代码语言:javascript
复制
[
    {
        "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函数来实现这一点?

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2013-09-12 20:34:28

在过滤过程中,我可能会使用一个标志对象(编辑:我不会再使用了,请看答案末尾关于use 2015的Set__的注释),如下所示:

代码语言:javascript
复制
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来完成它,当然,它只是有点冗长:

代码语言:javascript
复制
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;
  • 在ES2015中,您可以使用Set来代替: const标志=新集();const newPlaces =places.filter(条目=> { if (flags.has(entry.city){返回false;} flags.add(entry.city);返回true;};
票数 69
EN

Stack Overflow用户

发布于 2020-08-14 19:28:40

您可以使用filter使用Set,方法是只包含属性值尚未添加到Set (之后应该添加到Set)的元素。这可以使用逻辑和运算符(&&)在一行中完成。使用这种数据结构具有次线性查找次数(通常为O(1))的优点。

下面是一个通用函数,用于根据特定属性(prop)从对象数组(arr)获得唯一的对象数组。注意,在重复的情况下,只保留具有属性值的第一个对象。

代码语言:javascript
复制
const getUniqueBy = (arr, prop) => {
  const set = new Set;
  return arr.filter(o => !set.has(o[prop]) && set.add(o[prop]));
};

演示:

代码语言:javascript
复制
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'));

票数 8
EN

Stack Overflow用户

发布于 2016-07-20 04:27:01

https://lodash.com/docs#uniqBy

https://github.com/lodash/lodash/blob/4.13.1/lodash.js#L7711

代码语言:javascript
复制
/**
 * 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 }]
 */
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18773778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档