我和D3一起使用javascript。我正在创建一组节点,我希望能够单击它们,并将该节点的ID添加到数组中,以便我可以将该数组打印到控制台以查看所选节点并对所选节点执行任何操作。 (基本上选择并取消选择节点)
我已完成点击事件,因此节点的ID将转到所选数组。但是我想在它进入列表之前检查这个数组,看它是否已经存在,所以没有重复的信息。
selectedNodesArray=[];
for(var i = 0; i< selectedNodesArray.length; i++)
{
if(selectedNodesArray[i] === d.coreId)
{
console.log("that node is already selected");
} else
{
selectedNodesArray.push(d.coreId);
}
}
console.log(selectedNodesArray);
}
上面是我的for循环,我不明白为什么它不起作用。有任何想法吗 ?
回答T.J.Crowder
if (!selectedNodesArray.some(function(entry) { return entry == d.coreId; })) {
selectedNodesArray.push(d.coreId);
}
答案 0 :(得分:4)
为什么不使用&#34; indexOf()&#34;数组的方法,以找出该项目是否已存在于数组中?如果它存在则返回项目的位置,否则返回-1。这比通过For循环要快得多。
if(selectedNodesArray.indexOf(d.coreId)===-1){
selectedNodesArray.push(d.coreId);
}else{
console.log("that node is already selected");
}
现在,为了删除已存在的项目,您可以使用splice()。 首先使用indexOf()查找项目,然后使用splice()从列表中删除该项目。
答案 1 :(得分:3)
如果我认为我理解你要问的是什么,你只想知道一个元素是否已经存在于数组中,你可以使用indexOf()
。
if(selectedNodesArray.indexOf(d.coreId) === -1){
// push here because a value of -1 means it's not in the array
}
答案 2 :(得分:2)
上面是我的for循环,我不明白为什么它不起作用。任何想法?
您为每个不匹配的元素执行了push
。因此,如果你的数组有[1,2,3]并且你正在寻找2,你将最终得到[1,2,3,2,2],因为你每次看到一个条目时你都添加了2不是2。
你可以通过使用一个标志来解决这个问题,如果没有设置标志就可以在循环之后进行修复,或者只是在找到条目时断开循环然后再按i < selectedNodesArray.length
。
但对我来说,这是Array#indexOf
的案例(请参阅Barry's answer)或Array#some
:
if (!selectedNodesArray.some(function(entry) { return entry == d.coreId; })) {
selectedNodesArray.push(d.coreId);
}
Array#some
按顺序为数组中的每个条目调用一次回调函数,直到您的回调返回true
或它到达数组的末尾。如果您的回调曾返回true
,则返回true
,否则返回false
。它存在于所有现代浏览器中。如果您需要支持IE8或其他类似的过时浏览器,可以将其填充。