获取具有唯一值的数组的长度

3

我有一个包含一些对象的数组。我想将这些对象相互比较。如果fromIdtoId属性都相同,那么就是重复。

例如:

const data = [{
  fromId: 1,
  toId: 2,
  finished: true
}, {
  fromId: 1,
  toId: 2,
  finished: false
}, {
  fromId: 5,
  toId: 9,
  finished: false
}, {
  fromId: 1,
  toId: 5,
  finished: true
}, {
  fromId: 2,
  toId: 1,
  finished: false
}];

$(document).ready(() => {
  const duplicates = data.filter(x =>
    data
    .filter(y => y.fromId == x.fromId && y.toId == x.toId)
    .length > 1
  );

  console.log(duplicates);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

我想获取这个数据数组的长度,但只包含唯一的值。我尝试删除所有重复的值,并在此处找到了解决方案

获取数组中所有非唯一值(即:重复/多个出现次数)

const data = [1, 2, 3, 4, 5, 2, 2, 6, 7, 8, 2, 9, 2, 2, 2, 2, 2];

$(document).ready(() => {
  const uniqueValues = data.filter((connection, index) => data.indexOf(connection) == index);

  console.log(uniqueValues);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

但在这个解决方案中,我只是对整个对象使用了indexOf。如何比较fromIdtoId并删除相同匹配项上的重复内容?
从原始数组中,我将去掉其中一个。
{
      fromId: 1,
      toId: 2,
      finished: false
    }

因为fromIdtoId已经存在于另一个对象中。

6个回答

1
不要将一个filter嵌套在另一个filter中(运行时复杂度高),因为您只需要查找结果唯一数组的长度,所以可以将每个fromIdtoId组合成一个字符串,将该字符串放入Set中(仅保留唯一值),然后检查Set的大小:

const data=[{fromId:1,toId:2,finished:!0},{fromId:1,toId:2,finished:!1},{fromId:5,toId:9,finished:!1},{fromId:1,toId:5,finished:!0},{fromId:2,toId:1,finished:!1}];

const idSet = new Set(data.map(({ fromId, toId }) => fromId + '_' + toId));
console.log(idSet.size);


1
你可以使用Array.reduce()过滤具有唯一对象的数组,然后将长度值与唯一数组一起获取:

const data = [{
  fromId: 1,
  toId: 2,
  finished: true
}, {
  fromId: 1,
  toId: 2,
  finished: false
}, {
  fromId: 5,
  toId: 9,
  finished: false
}, {
  fromId: 1,
  toId: 5,
  finished: true
}, {
  fromId: 2,
  toId: 1,
  finished: false
}];

$(document).ready(() => {
  var uniqueArray = data.reduce((acc, obj)=>{
    var existObj = acc.find(item => item.fromId === obj.fromId && item.toId === obj.toId);
    if(existObj){
      return acc;
    }
    acc.push(obj);
    return acc;
  },[]);
console.log('unique array ', uniqueArray);
console.log('length of unique object ', uniqueArray.length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


0
你可以创建一个新数组,并使用jQuery的inArray函数检查元素是否已经存在,只需推送一次即可:

const data = [{
  fromId: 1,
  toId: 2,
  finished: true
}, {
  fromId: 1,
  toId: 2,
  finished: false
}, {
  fromId: 5,
  toId: 9,
  finished: false
}, {
  fromId: 1,
  toId: 5,
  finished: true
}, {
  fromId: 2,
  toId: 1,
  finished: false
}];

$(document).ready(() => {
   
  var filtered = [];
  $.each(data, function(i, item){
      if($.inArray(item, filtered) === -1){
        filtered.push(item);
      }
      
      
  });
  console.log(filtered.length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

jQuery inArray()


0

0

尝试使用简单的forEach - 这是纯JS而不是ES5/6或jQuery

const data = [{fromId: 1,toId: 2,finished: true},{fromId: 1,toId: 2,finished: false}, {fromId: 5,toId: 9,finished: false}, {fromId: 1,toId: 5,finished: true}, {fromId: 2, toId: 1, finished: false }];
var combos = [];
var  dupes = [];
var unique = [];

data.forEach(function(item){
  var combo = ""+item.fromId+"."+item.toId;
  if (combos.indexOf(combo) == -1) {
    combos.push(combo);
    unique.push(item);
  }
  else {
    dupes.push(item);
  }
});
console.log("dupes",dupes);
console.log("unique",unique,unique.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


0

是的,有很多选择... 我会给你另一个使用 lodash/fp 的选项:

假设你已经有了:

import {flow, map, uniq} from 'lodash/fp'

做这个:

const count = flow(
    map(o => o.fromId + '.' + o.toId),
    uniq,
  )(data).length

console.log('Count: ', count)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接