当前位置: 首页 > 知识库问答 >
问题:

按属性创建唯一对象数组

夏意蕴
2023-03-14

我创建了一个对象数组,如下所示:

[
    {
        "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"
    }
]

我正在尝试创建一个新数组,该数组过滤位置,使其仅包含不具有相同城市属性的对象(lat/lng重复项可以)。是否有内置的JS或Jquery函数来实现这一点?

共有3个答案

谷梁浩思
2023-03-14

您可以使用Set过滤,方法是仅包含具有尚未添加到Set的属性值的元素(之后应将其添加到Set)。这可以使用逻辑和运算符在一行中完成(

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

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'));

桑睿识
2023-03-14

es6的最短但不是最佳性能解决方案(请参阅下面的更新):

function unique(array, propertyName) {
   return array.filter((e, i) => array.findIndex(a => a[propertyName] === e[propertyName]) === i);
}

性能:https://jsperf.com/compare-unique-array-by-property

祝宾白
2023-03-14

我可能会在过滤过程中使用flags对象(编辑:我不会再使用了,请参阅关于ES2015的设置的答案末尾的注释),如下所示:

var flags = {};
var newPlaces = places.filter(function(entry) {
    if (flags[entry.city]) {
        return false;
    }
    flags[entry.city] = true;
    return true;
});

它使用ECMAScript 5(ES5)中的数组#过滤器,ECMAScript 5是可以填充的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);
    }
});

以上两种情况都假设应该保留具有给定城市的第一个对象,而丢弃所有其他对象。

注意:正如user2736012在下面指出的那样,对于名称恰好与对象上存在的属性相同的城市,我的测试if(flags[entry.city])将为true。原型,例如toString。在这种情况下不太可能,但有四种方法可以避免这种可能性:

>

  • (我通常首选的解决方案)创建没有原型的对象:var标志=Object.create(null);。这是ES5的一个特性。请注意,对于像IE8这样的过时浏览器,这是无法实现的(Object.create的单参数版本可以,除非该参数的值为null)。

    使用hasOwnProperty进行测试,例如if(flags.hasOwnProperty(entry.city))

    为任何Object.prototype属性添加一个前缀,例如xx

      var key = "xx" + entry.city;
      if (flags[key]) {
          // ...
      }
      flags[key] = true;
    

    从ES2015开始,您可以使用集合来代替:

      const flags = new Set();
      const newPlaces = places.filter(entry => {
          if (flags.has(entry.city)) {
              return false;
          }
          flags.add(entry.city);
          return true;
      });
    

  •  类似资料:
    • 问题内容: 我们如何用Swift语言(例如&在Objective-C中)创建唯一的对象列表。 问题答案: 从Swift 1.2(Xcode 6.3 beta)开始,Swift具有本机集合类型。从发行说明中: 包括一个新的数据结构,该结构提供具有完整值语义的独特元素的通用集合。它与之桥接,提供与和类似的功能。 以下是一些简单的用法示例: 但是还有更多可用的方法。 更新: 现在,集合也记录在Swift

    • 问题内容: 我需要通过对象属性之一的一个属性比较对象数组。 我在做 : 它没有编译,有人知道怎么做吗? 谢谢。 问题答案: 这是代码中导致错误的部分 您可以创建对特定类型的任意对象的(静态或非静态)方法的引用。对任何类型的对象的方法的引用如下所示: 但是方法引用不是对象,并且没有成员可以访问。使用此代码,您尝试访问引用的成员变量(并且不能) 另外,方法引用不是类,因此您不能从它们中获取另一个方法引

    • 下表(按对象名称排序)列出了 Microsoft Office 中已有对象添加的属性。对象属性CommandBarButton Mask Picture CommandBars DisableAskAQuestionDropdown DisableCustomizeFileDialog AllowMultiSelect ButtonName DialogType FilterIndex Filte

    • 给定一个有效的属性标识符数组和一个值的数组,返回一个将属性关联到值的对象。 由于一个对象可以有未定义的值,但不存在未定义的属性,该属性数组用于使用 Array.reduce() 来决定结果对象的结构。 const zipObject = (props, values) => props.reduce((obj, prop, index) => ((obj[prop] = values[inde

    • 出于业务逻辑的原因,我希望能够创建一个具有属性的对象。但我显然不能 因为是在Python中具有特殊含义的保留关键字。但是,使用或动态获取属性也存在同样的问题。我可以这样做吗,还是必须让属性名?

    • 我需要根据下面的2个属性从数组中找到唯一的对象。当“类”和“票价”匹配时,我需要提取唯一的值并在结果数组中获取它们。 来源: 预期结果: 我在SO中查看并能够找到基于一个属性过滤的答案(按属性创建唯一对象数组),但无法找到基于2个属性的答案。