我正在观看视频,了解如何创建一个函数来替换数组中的所有重复项。例如,如果数组由[1,1,2]组成,则该函数将仅输出[1,2]。
观看视频后,最终代码为:
let removeDuplicates = (a)=>{
let input = {};
let output = [];
for (let i = 0; i < a.length; i++){
let el = a[i];
if (!(el in input)){
input[el] = true;
output.push(el)
}
};
return output;
}
我理解大部分功能,但我在if语句中无法理解HashTable输入的使用方式。我的问题是 1)我们如何检查输入中的el是否为输入以前从未在函数中使用过。 2)为什么我们设置输入[el] = true。
对不起,如果这不是世界上最明显的问题。我无法理解这个问题。在此先感谢您的帮助。
答案 0 :(得分:1)
input
在for循环之外声明,因此它存在于函数之前,并且在整个过程中仍然存在于for循环范围内。
More info about the let
keyword and its scoping。el
input
键即可
醇>
答案 1 :(得分:1)
input
从空{}
开始,然后在第一个循环看起来像{"1": true}
之后,在第二个循环后,没有任何变化,在第三个循环看起来像{"1": true, "2": true}
之后
即使我们将代码更改为以下任何一项,代码仍然有效:
input[el] = undefined;
input[el] = null;
input[el] = el;
input[el] = "blah";
input[el] = "";
input[el] = false;
input[el] = 0;
因为input
包含键“1”,所以值1
将永远不会多次添加到output
数组中。处理此问题的测试也可以从以下更改:
if (!(el in input)){
为:
if( !input.hasOwnProperty(el) ) {
请参阅:Object.prototype.hasOwnProperty
您还可以在for循环结束时记录输入内容,看看发生了什么:
console.log(JSON.stringify(input));
我使用JSON.stringify来避免任何“有用的”浏览器控制台更新以前记录的对象的内容。
基本上,玩代码看看会发生什么。如果您只读过如何编码,那么您将永远无法编码。
以下是您可以运行/修改以查看其工作原理的代码片段:
let a = [1, 1, 2];
let input = {};
let output = [];
console.log(JSON.stringify(input));
for (let i = 0; i < a.length; i++){
let el = a[i];
if (!(el in input)){
//if (input.hasOwnProperty(el))){
input[el] = true;
//input[el] = undefined;
//input[el] = null;
//input[el] = el;
//input[el] = "blah";
//input[el] = "";
//input[el] = false;
//input[el] = 0;
output.push(el)
}
console.log(JSON.stringify(input));
}
console.log(output);
并且为了完整性,您还可以通过简单地执行以下操作来消除伪哈希input
对象(尽管对于大型数组,性能方面可能要慢得多):
let a = [1, 1, 2];
let output = [];
for (let i = 0; i < a.length; i++){
if (output.indexOf(a[i]) === -1 ){
output.push(a[i])
}
}
console.log(JSON.stringify(output)); // [1,2]
答案 2 :(得分:0)
基本上,代码使用input
变量来保存已经在传递的a
数组中迭代的所有值。 Input
从空开始,并在我们通过a
进行迭代时填充。它在for循环的范围内。
代码集input[el] = true
,但实际上您可以将input[el]
设置为任何内容并让代码仍然有效。所有条件!(el in input)
都在检查输入是否有一个键为el
的对象。在这种情况下,该密钥的值无关紧要。
使用a is [1,1,2]
...
首先将input
对象设为空。
然后,您接受a
,1
的第一个元素,并设置el = 1
。
如果1不在input
(不是),则设置input[1] = true
,然后将1推到output
数组。
接下来,您接受第二个元素1并设置el = 1
。
!(el in input)
为false,因为1已经在input
对象中。你忽略了这一点并继续a
中的下一个元素。
最后,检查2并设置el = 2
。如果2不在input
(不是),则设置input[2] = true
,然后将2推到output
数组。
更直接的方法是将数组转换为集合。
或者,您可以使用output
数组并对传入的indexOf
变量的每个元素使用a
方法,看看它是否已存在于输出中 - 如果不存在,添加它。否则继续。
答案 3 :(得分:0)
好问题,其他人可能会问同样的事情。实际上,一旦你理解了它的工作原理,你的第二个问题就会回答你的第一个问题,所以让我们从那里开始。
2)要理解的第一件事是我们关心的是返回的输出数组没有任何重复,所以我们设置input [el] = true,因为我们希望这发生。通过if检查的任何值都会添加到输入对象,然后添加到我们所需的输出。在这种情况下,输入的行为类似于HashTable或Set:
1)通过这种理解,我们可以看到输入对象是在循环之外但在函数内声明的,所以它的全部目的只是一个容器(Set),在我们添加之前通过if检查来检查我们输出的一个项目。
这可以通过以下方式测试:
let input = {};
input["One"] = true;
console.log(input); //outputs {One: true}