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

收集JavaScript数组中的唯一对象

夏烨霖
2023-03-14

假设我有以下对象数组

var firstDataSet = [
  {'id': 123, 'name': 'ABC'},
  {'id': 456, 'name': 'DEF'},
  {'id': 789, 'name': 'GHI'},
  {'id': 101, 'name': 'JKL'}
];

var secondDataSet = [
  {'id': 123, 'name': 'ABC', 'xProp': '1q'},
  {'id': 156, 'name': 'MNO', 'xProp': '2w'},
  {'id': 789, 'name': 'GHI', 'xProp': '3e'},
  {'id': 111, 'name': 'PQR', 'xProp': '4r'}
];

现在我想收集具有唯一对象(匹配idname)的数组,即。

var firstDataSet = [
  {'id': 123, 'name': 'ABC', 'xProp': '1q'},
  {'id': 456, 'name': 'DEF'},
  {'id': 789, 'name': 'GHI', 'xProp': '3e'},
  {'id': 101, 'name': 'JKL'},
  {'id': 156, 'name': 'MNO', 'xProp': '2w'},
  {'id': 111, 'name': 'PQR', 'xProp': '4r'}
];

我能收集所有的东西

Array.prototype.unshift.apply(firstDataSet , secondDataSet );

但不知道如何过滤掉重复的。有什么建议吗?

编辑:两个不同数组上的我的对象不相同。至少基于属性的数量。

共有3个答案

章海
2023-03-14

我们将使用contat组合这两个数组,然后使用filter过滤结果数组。对于每个元素,我们将使用findIndex查找具有相同id和名称的第一个元素的索引。如果该索引与当前索引相同,这意味着这是该id和name的第一次出现,所以我们只是让它通过。否则,我们将在第一次出现时添加新字段,并过滤掉它。

function combine(a1, a2) {

  function match(e1, e2) { return e1.id === e2.id && e1.name === e2.name); }

  return a1.concat(a2) . filter((e1, i, a) => {
    let firstIndex = a.findIndex(e2 => match(e1, e2));
    if (i === firstIndex) return true; // this is the first occurrence
    a[firstIndex].xProp = e2.xProp;    // copy over property
    return false;                      // filter out
  });

}

如果您想处理任意属性,而不仅仅是xProp,那么将相关行更改为以下内容

a[firstIndex] = Object.assign(e2, a[firstIndex]);

这将使用在当前引用上复制其所有属性的结果替换第一个引用,包括它可能具有的任何其他属性。

强制性免责声明:一如既往,根据您的环境,您可能没有箭头函数、或数组#findIndex对象。分配。在这种情况下,请根据需要重写/多边形填充/传输。

伏德义
2023-03-14

这可以通过扩展下面的设置类来实现

    var firstDataSet = [
      {'id': 123, 'name': 'ABC'},
      {'id': 456, 'name': 'DEF'},
      {'id': 789, 'name': 'GHI'},
      {'id': 101, 'name': 'JKL'}
    ];

    var secondDataSet = [
      {'id': 123, 'name': 'ABC', 'xProp': '1q'},
      {'id': 156, 'name': 'MNO', 'xProp': '2w'},
      {'id': 789, 'name': 'GHI', 'xProp': '3e'},
      {'id': 111, 'name': 'PQR', 'xProp': '4r'}
    ];

    Array.prototype.unshift.apply(firstDataSet , secondDataSet );

    //console.log(firstDataSet)

    class UniqueSet extends Set {
            constructor(values) {
                super(values);

                const data = [];
                for (let value of this) {
                    if (data.includes(JSON.parse(value.id))) {
                        this.delete(value);
                    } else {
                        data.push(value.id);
                    }
                }
            }
          }

console.log(new UniqueSet(firstDataSet))

工作环节

潘智刚
2023-03-14

这是最初的问题。

使用集合

使用Set对象可以存储任何类型的唯一值,无论是基元值还是对象引用。

还可以使用对象文字。

var list = [JSON.stringify({id: 123, 'name': 'ABC'}), JSON.stringify({id: 123, 'name': 'ABC'})]; 
var unique_list = new Set(list); // returns Set {"{'id': 123, 'name': 'ABC'}"}
var list = Array.from(unique_list); // converts back to an array, and you can unstringify the results accordingly.

有关将集合构造回数组的更多方法,请按照此处的说明进行操作。如果您不能使用ES6(这是定义Set),那么对于较旧的浏览器有一个polyfill。

不幸的是,这些对象不再是严格的重复对象,例如,无法使用Set以友好的方式处理这些对象。

解决这类问题的最简单方法是迭代对象数组,识别那些具有重复属性值的对象,并使用splice就地消除这些对象。

 类似资料:
  • 问题内容: 我需要做一些实验,并且需要知道javascript中对象的某种唯一标识符,因此我可以查看它们是否相同。我不想使用相等运算符,我需要类似python中的id()函数的功能。 是否存在这样的东西? 问题答案: 更新 我下面的原始答案写在6年前,其风格与时代和我的理解相吻合。为了回应评论中的某些对话,一种更现代的方法如下: 如果您对旧版浏览器有要求,请在此处查看的浏览器兼容性。 原始答案保留

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

  • 问题内容: 我有两节课 假设我在代码中使用对象B [say ],并在最终使用它后将其设置为。我知道B的对象现在可用于垃圾回收了。 我知道在将b设置为null之后,它将 立即有资格 进行垃圾回收吗?但是类型A的对象呢?将B设置为以后,是否可以 立即 将其用于垃圾回收?还是 在B被垃圾回收之后 才有资格 进行 垃圾回收 ? 从理论上讲,在对B进行垃圾收集之前,还有参考吗?因此,SUN JVM编译器将在

  • 我有一组这样的对象: 我想对其进行过滤,以便每个唯一名称都有一个实例,该实例必须给出小于或等于40的最大值。如果过滤,上述情况将返回: 最终的数组不必按任何特定的顺序排序。

  • 问题内容: 在处理从YQL返回的JSON时,我发现自己正在寻找一种从数组中提取所有唯一值的方法。 代码看起来有点“忙”,我想知道是否有更优雅的方法从数组中提取唯一值。 问题答案: 您可以使用indexOf来检查元素是否在数组中。 或者如果您具有唯一的ID或名称,则使用对象而不是数组:var output = {}

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