我需要一些帮助来迭代数组,我一直被卡住或重新发明轮子。
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
如何检查数组中是否有两个(或更多)相同的名称值?我不需要计数器,如果数组值不唯一,只需设置一些变量。请记住,数组长度是动态的,数组值也是如此。
我需要一些帮助来迭代数组,我一直被卡住或重新发明轮子。
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
如何检查数组中是否有两个(或更多)相同的名称值?我不需要计数器,如果数组值不唯一,只需设置一些变量。请记住,数组长度是动态的,数组值也是如此。
使用array.prototype.map和array.prototype.some:
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){
return valueArr.indexOf(item) != idx
});
console.log(isDuplicate);
ECMA 脚本 6 版本
如果您处于支持 ECMA Script 6's 的环境中Set
,那么您可以使用Array.prototype.some
一个Set
对象,如下所示
let seen = new Set();
var hasDuplicates = values.some(function(currentObject) {
return seen.size === seen.add(currentObject.name).size;
});
在这里,我们将每个对象插入name
到 中,Set
并检查size
添加前后是否相同。这是有效的,因为Set.size
返回基于唯一数据的数字(如果数据唯一,则 set 仅添加条目)。如果/当你有重复的名字时,大小不会增加(因为数据不是唯一的),这意味着我们已经看到了当前的名字,它会返回 true。
ECMA 脚本 5 版本
如果你没有Set
支持,那么你可以使用一个普通的 JavaScript 对象本身,就像这样
var seen = {};
var hasDuplicates = values.some(function(currentObject) {
if (seen.hasOwnProperty(currentObject.name)) {
// Current name is already seen
return true;
}
// Current name is being seen for the first time
return (seen[currentObject.name] = false);
});
一样可以写得简洁,像这样
var seen = {};
var hasDuplicates = values.some(function (currentObject) {
return seen.hasOwnProperty(currentObject.name)
|| (seen[currentObject.name] = false);
});
注意:在这两种情况下,我们都使用Array.prototype.some
它,因为它会短路。当它从函数中获得一个真值时,它会true
立即返回,它不会处理其余的元素。
在 TS 和 ES6 中,您可以创建一个具有唯一属性的新 Set,并将其大小与原始数组进行比较。
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName3' },
{ name: 'someName1' }
]
const uniqueValues = new Set(values.map(v => v.name));
if (uniqueValues.size < values.length) {
console.log('duplicates found')
}
要知道简单数组是否有重复,我们可以比较相同值的第一个和最后一个索引:
功能:
var hasDupsSimple = function(array) {
return array.some(function(value) { // .some will break as soon as duplicate found (no need to itterate over all array)
return array.indexOf(value) !== array.lastIndexOf(value); // comparing first and last indexes of the same value
})
}
测试:
hasDupsSimple([1,2,3,4,2,7])
// => true
hasDupsSimple([1,2,3,4,8,7])
// => false
hasDupsSimple([1,"hello",3,"bye","hello",7])
// => true
对于对象数组,我们需要先将对象值转换为简单数组:
使用以下命令将对象数组转换为简单数组map
:
var hasDupsObjects = function(array) {
return array.map(function(value) {
return value.suit + value.rank
}).some(function(value, index, array) {
return array.indexOf(value) !== array.lastIndexOf(value);
})
}
测试:
var cardHand = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"three" },
]
hasDupsObjects(cardHand);
// => false
var cardHand2 = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"ten" },
]
hasDupsObjects(cardHand2);
// => true
如果您正在寻找布尔值,最快的方法是
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
// solution
var hasDuplicate = false;
values.map(v => v.name).sort().sort((a, b) => {
if (a === b) hasDuplicate = true
})
console.log('hasDuplicate', hasDuplicate)