我在这里有这段代码,该代码应考虑这些不同项的长度,如果长度大于4,则应删除这些值。但是,它说if(array [i] .length> 4)未定义
let words = ["Apple", "Ben", "Ice", "Dog", "Tornado"];
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
console.log(array[i].length);
}
if (array.length > 4) {
array[i].splice();
}
}
console.log(removeWords(words));
答案 0 :(得分:3)
您可以使用Array.filter()
let words = ["Apple", "Ben", "Ice", "Dog", "Tornado"].filter(w => w.length <= 4);
console.log(words);
答案 1 :(得分:2)
恐怕这段代码有很多问题。已经提供了简单的答案:使用filter
。如果您仅想知道这些,那就太好了。如果您想通过此方法获得可用的版本,请执行以下步骤:
我们从
开始let words = ["Apple", "Ben", "Ice", "Dog", "Tornado"];
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
console.log(array[i].length);
}
if (array.length > 4) {
array[i].splice();
}
}
console.log(removeWords(words));
首先要注意的是,我们在调用console.log
的结果上调用removeWords
。但是removeWords
不返回任何内容。因此,让我们首先解决该问题:
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
console.log(array[i].length);
}
if (array.length > 4) {
array[i].splice();
}
return array; // <--------------------- added
}
但是现在让我们看看您正在执行的测试。 if (array.length > 4)
。您想测试循环内的 ,因为您想测试列表中的每个单词。您已经有了循环,但是它仅包含console.log
语句的调试代码。让我们将其移出并在其中移入测试及其相关更改:
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
if (array.length > 4) { // ---\
array[i].splice(); // --- >---- moved inside loop
} // ---/
}
return array;
}
但是现在让我们看一下实际测试。我们应该检查 word 的长度是否大于4,而不是 array 的长度。因此,我们需要检查array[i] > 4
:
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
if (array[i].length > 4) { // <------ changed
array[i].splice();
}
}
return array;
}
在splice
调用中,我们遇到了相反的问题。当您想在数组上执行此操作时,尝试在单词上调用splice
。您要删除数组中第i
个索引处的一个元素。我们可以通过
function removeWords(array) {
for (var i = 0; i < array.length; i++) {
if (array[i].length > 4) {
array.splice(i, 1); // <----------- changed
}
}
return array;
}
下一个问题更加微妙。而且它甚至不会影响您的测试用例。但是,如果我们针对以下列表运行此函数:["Apple", "Ben", "Ice", "Dog", "Tornado", "Windshield", "Axe"]
,我们将返回["Ben", "Ice", "Dog", "Windshield", "Axe"]
。由于您的循环和"Windshield"
调用之间存在交互,因此我们在此处包含splice
。我们会继续努力,直到将i
设置为3
。此时,我们的数组包括["Ben", "Ice", "Dog", "Tornado", "Windshield", "Axe"]
,因为我们已经删除了“ Apple”。我们检查索引3,发现“龙卷风”有四个以上的字母,再次splice
,剩下["Ben", "Ice", "Dog", "Windshield", "Axe"]
。但是现在索引是4,测试词是"Axe"
,我们已经跳过了“ Windshield”!
之所以会这样,是因为,当您要测试数组中的每个单词时,您的splice
调用会随着您的更改数组的长度。解决此问题的一种方法是反向循环。从头开始,splice
仅会影响您已经测试过的事物的索引。可能看起来像这样:
function removeWords(array) {
// +--------------+-----+- changed
// | | |
// v v v
for (var i = array.length - 1; i >= 0; i--) {
if (array[i].length > 4) {
array.splice(i, 1);
}
}
return array;
}
这是代码的第一个工作版本。我们可以把它留在那里。但是仍然存在潜在的问题。您可以随时更改输入。有很强的思想流派发现这是一件非常可怕的事情。因此,让我们先对其进行复制,然后再进行更改并返回,而不是更改原始输入数据。我们可以采用多种方法对输入进行浅表克隆,包括使用slice
或concat
。现代的大概是这样使用传播符号:
function removeWords(words) {
// ^--------+---------- changed
let array = [...words] // <---'
for (var i = array.length - 1; i >= 0; i--) {
if (array[i].length > 4) {
array.splice(i, 1);
}
}
return array;
}
这是该函数的一个合理版本...如果我们还没有Array.prototype.filter
可用的话。您可以在以下代码段中看到它的运行情况:
function removeWords(words) {
let array = [...words]
for (var i = array.length - 1; i >= 0; i--) {
if (array[i].length > 4) {
array.splice(i, 1);
}
}
return array;
}
let words = ["Apple", "Ben", "Ice", "Dog", "Tornado"];
let words2 = ["Apple", "Ben", "Ice", "Dog", "Tornado", "Windshield", "Axe"];
console.log (removeWords(words));
console.log (removeWords(words2));
console.log ("--------------\nOriginals Untouched\n--------------")
console.log (words);
console.log (words2);
.as-console-wrapper {min-height: 100% !important; top: 0}