【问题标题】:How to pass a function only after an entire array has been read and not for each element?如何仅在读取整个数组而不是每个元素之后才传递函数?
【发布时间】:2018-09-09 17:52:43
【问题描述】:

我试图在读取数组时运行一个函数,但不是对每个元素运行该函数,我目前正在使用 forEach,我想让脚本读取整个数组,然后传递一个函数。

我想说的是:

data.forEach(movie => {
    // Log each movie's title
    //console.log(movie.title);

    // Check if the userWord matches
    if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
        alert("YES");                   
    } else {
        alert("NO").
    }
});

假设我的数组是:array = ["Aa", "Ba", "Ca", "Da"];

如果用户输入:a,那么脚本会alert("YES") 4 次,我只想让它在迭代结束时提醒一次。

同样的例子,如果用户输入:B,那么脚本会先alert("NO")一次,然后alert("YES"),然后alert("YES") 2次,我想做最后只是alert("YES")once。

最后,如果用户输入:Ferrari,那么脚本会alert("NO")四次,我只希望它最后是alert("NO")

我试图在这里说得很清楚,这就是为什么发生了三个“案例”。

最后,我想知道是否有一种方法与forEach 或常见的for 有点相反。读取整个数组后才执行函数的东西。

【问题讨论】:

  • 您要检查是否有匹配的电影吗?
  • 完全是@ibrahimmahrir,我已经可以做到,但我在为用户打印答案时遇到问题。
  • 你真的需要循环整个数组吗?如果存在第一个匹配的元素,你就不能停下来吗?
  • @ibrahimmahrir 实际上我想显示是否有匹配项以及找到了哪些匹配项。但我认为通过人们在下面回答的some() 结构,我可以实现它。

标签: javascript arrays foreach


【解决方案1】:
  1. 将警报更改为布尔变量
  2. 删除 else(它只会覆盖任何匹配项)
  3. if bool 语句在循环外执行操作

如果您想要一个结果列表,您应该将名称存储在一个数组中并在循环之外 - 打印。

见下文:

非循环方法:

data = ["test","hello", "hello1"];
search = "lo"; 
const matches = data.filter(movie => movie.includes(search));

alert(matches) //array of only matches - only has hello and hello 1

我不知道循环是否有性能提升...我想您可以在大型数据集上进行并排比较

循环方法:

var matches = "";
data.forEach(movie => {
    // Check if the userWord matches
    if (movie.title.toUpperCase().includes(userWord.toUpperCase())) {
        matches += movie.title + "<br> ";
    }
});

if (matches.length > 0)
{
    document.getElementById("results").innerHTML = matches;
} else {
    alert("No match found");
}

您会在第一个循环中看到更多自定义,但我认为首先过滤数据是要走的路。

【讨论】:

  • 这段代码是用什么语言写的? Javascript 不是类型化语言。你的意思是var matches = "";
  • 我认为这正是我正在寻找的。我没有考虑将它存储在另一个数组中,但是现在你和其他人给出了这个提示。太棒了,谢谢!
  • 有了这个,我现在可以发布 cmets 了 :) 可能有一种非循环方式来做这件事,因为对于大型数据集来说循环可能会很慢...
  • 知道了,通过大数据集;多大?我的意思是,如果我必须遍历一个包含 100k 个元素的数组?我真的是 JS 新手,所以很多事情都不清楚。
  • 我也添加了一个非循环方法,它返回一个只有结果的数组,所以你仍然需要一个循环来自定义,只是过滤数据。 @samuellawrentz 更进一步。不知道什么是更好的性能明智。
【解决方案2】:

我认为你能得到的最接近的是some。这是示例

let data = ["test","hello", "hello1"];
let userWord = "el";
let res =  data.some(movie => movie.toUpperCase().includes(userWord.toUpperCase()));
console.log(res) // prints true- means there was at least one "match", so you can alert

【讨论】:

    【解决方案3】:

    您可以使用filter 数组函数来过滤与您的条件匹配的数组元素,然后最终仅在找到匹配项时发出警报。使用此方法,您可以获得与您的userWord 匹配的所有元素。也就是说,match 数组将包含所有可能的匹配项。

    var data = ['Aa', 'Bb', 'Cc', 'Dd'];
    var flag = false;
    var userWord = 'F'
    var match = data.filter(movie => movie.indexOf(userWord) !== -1);
    if(match.length)
    console.log('YES');
    else
    console.log('NO');

    【讨论】:

    • 将它存储在另一个数组中是我的收获,谢谢!
    【解决方案4】:

    如果我正确理解了这个问题,我相信如果谓词与数组中的至少一项匹配(如果我错了,请纠正我)。为此,您可以像这样使用some 方法:

    if (movies.some((movie) => movie.toUpperCase().includes(userWord.toUpperCase()))) {
      alert('YES');
    } else {
      alert('NO');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      相关资源
      最近更新 更多