所以我有一个包含一些对象的数组。我想将这些对象相互比较。如果fromId
的 AND 属性相同,则表示重复。
示例:
toId
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);
});
我想获取此数据数组的长度,但只能使用唯一值。我试图删除所有重复的值并在此处找到解决方案
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
<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
和fromId
并删除相同匹配项中的重复项?
我将从原始数组中删除一个
toId
因为{
fromId: 1,
toId: 2,
finished: false
}
和fromId
已经存在于另一个对象中。
答案 0 :(得分:2)
不是将filter
嵌套在另一个filter
中(糟糕的运行时复杂度),因为您只是在寻找唯一数组的长度,因此可以将每个fromId
和将toId
放入字符串中,然后将该字符串放入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 :(得分:2)
您可以使用Order
来过滤具有唯一对象的数组,然后将长度值与唯一数组一起获取:
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);
});
答案 2 :(得分: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()
答案 3 :(得分:0)
虽然对您的情况来说,SecretPerformance的答案可能更好,但是不比较项目标识的indexOf
替代方案是findIndex
。但是,这仅是ES6 +,但是大多数现代浏览器都实现了它(对不起,没有IE11)。
来源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
答案 4 :(得分: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>
答案 5 :(得分: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)