代码之家  ›  专栏  ›  技术社区  ›  Adrian Brand

在数组中查找第一个结果的javascript函数

  •  0
  • Adrian Brand  · 技术社区  · 7 年前

    我正在寻找一种函数方法来找到数组中的第一个结果。

    let result;
    for (let i = 0; i < array.length; i++) {
      result = functionThatCalulatesResult(array[i]);
      if (result) {
        break;
      }
    }
    

    是必由之路。

    const item = array.find(i => functionThatCalulatesResult(i));
    

    但现在我得重新计算结果。

    const result = array.reduce(
      (result, item) => result ? result : functionThatCalulatesResult(i), 
      undefined
    );
    

    但是reduce继续遍历所有不需要迭代的项。

    我在找一些像

    const result = firstResult(array, i => functionThatCalulatesResult(i));
    

    返回函数的第一个truthy结果,而不迭代超过第一个结果的项。

    我能想到的最有效的办法是

    const firstResult = (array, func) => {
      let result;
      array.some(i => result = func(i));
      return result;
    }
    

    但它并不是纯功能的结果变异。

    编辑:

    对于询问数组中是什么的人,我试图找到在这个函数中找到返回排序方向的参数的最有效的方法。

    https://stackblitz.com/edit/typescript-syhjq4

    我使用的是reduce,但是由于排序函数对数组进行了变异,所以我已经切换到了带变异的some。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Dacre Denny    7 年前

    如果我正确地理解了你的问题,也许你可以先减少 array 价值观 Set .

    这意味着接下来 find() 如下所示,只对唯一值进行操作(这避免了重复迭代和重新处理 functionThatCalulatesResult() 在重复的数组项上):

    // Mock functionThatCalulatesResult() to illustrate this answers
    // idea. The function returns truthy when value 5 encountered
    function functionThatCalulatesResult(i) {
      console.log('visiting:', i )      
      if(i === 5) {
        return true;
      }  
    }
    
    var array = [1,2,3,1,3,1,5,6];
    
    // Reducing array to unique set of values avoid reprocessing of 
    // functionThatCalulatesResult() on duplicate values that don't 
    // return truthy
    var result = Array.from(new Set(array)).find(functionThatCalulatesResult);
    
    console.log('result', result) 
        2
  •  0
  •   Michiel Dral    7 年前

    这很棘手,因为据我所知,用标准的“函数式”方法无法做到这一点。

    老实说,最好的方法是将命令循环封装在函数中。 我知道这可能不是最令人满意的答案,但我个人发现,当您有时使用命令式代码时,您的代码实际上会变得更干净:

    let map_find = (array, map_fn) => {
      for (let item of array) {
        let result = map_fn(array[i]);
        if (result) {
          return result;
        }
      }
    }
    
    // use map_find like it is super functional
    const item = map_find(array, i => functionThatCalulatesResult(i));
    

    (也) for (... of ...) 看起来还是比for循环好多了;))