【问题标题】:Return each array item incrementally with each function call when passed as callback当作为回调传递时,随着每个函数调用递增地返回每个数组项
【发布时间】:2022-01-19 01:48:56
【问题描述】:

我有一个对象数组,例如: [{}, {}, {}, {}, {}]; 我还有一个递归函数,它接受一个函数作为参数:

function recursiveFunction(getResponse) {
   const result = getResponse();
   
   const conditionMet = check(result);

   if(conditionMet) {
      return result;
   }

   return recursiveFunction(getResponse);
} 

如何创建一个函数 getResponse,以便每次在 recursiveFunction 中调用它时,它都会返回我数组的下一次迭代?

例如,在每次递归时,它应该获取数组中的下一个对象:

function getResponse(index) {
   return array[index ++];
}

当我调用它时:

const firstIndex = -1; // Because index ++ in function
const result = recursiveFunction(getResponse(firstIndex));

我明白为什么它只返回第一个值,但我不确定如何修改它以在再次调用它时返回数组中的下一个索引。

【问题讨论】:

  • getResponse() 应该是包含当前数组索引和数组的环境中的闭包。它可以增加索引并返回该数组元素。
  • 这似乎是一个家庭作业,所以不要索要代码。
  • 我想我应该提供上下文。在我的例子中,recursiveFunction 是一个函数,它递归地调用一个 api 端点,然后在满足条件时最终返回(本质上是轮询同一个端点)。我正在尝试为该特定函数编写一个单元测试,而我的数组是响应的模拟,因此为什么我使用回调,所以我可以传入函数来发出 GET 请求并传入另一个函数,它只是返回我的模拟中的响应。
  • 好的,这不是家庭作业。但是我们仍然希望您先尝试解决它,然后我们会帮助您解决它。
  • 在 ES6 中,您可以在包含 let 数组和索引变量的块中创建一个函数。在 ES5 中,使用 IIFE 为变量创建环境。

标签: javascript arrays recursion


【解决方案1】:

您应该将函数作为参数传递,而不是调用函数。

const result = recursiveFunction(getResponse);

另外,如果将索引初始化为-1,则需要使用++index,而不是index++

【讨论】:

    【解决方案2】:

    在 JavaScript 中执行此操作的方法是使用内置的 Iteration Protocol -

    const myinput =
      [ {a:1}, {b:2}, {c:3}, {d:4} ]
      
    const it =
      myinput.values()
      
    console.log(it.next())
    console.log(it.next())
    console.log(it.next())
    console.log(it.next())
    console.log(it.next())
    {value: {a:1}, done: false}
    {value: {b:2}, done: false}
    {value: {c:3}, done: false}
    {value: {d:4}, done: false}
    {value: undefined, done: true}
    

    您可以创建自己的 iter 函数,该函数返回一个与您描述的函数类似的函数 -

      
    function iter(iterable) {
      const it = iterable.values()
      return () => it.next().value
    }
    
    const inputA = [1,2,3]
    const inputB = ["a","b","c"]
    
    const nextA = iter(inputA)
    const nextB = iter(inputB)
    
    console.log(nextA()) // 1
    console.log(nextA()) // 2
    console.log(nextB()) // "a"
    console.log(nextB()) // "b'
    console.log(nextA()) // 3
    console.log(nextB()) // "c"
    console.log(nextA()) // undefined
    console.log(nextB()) // undefined

    在您的程序中,您必须检查 undefined 才能知道何时没有剩余值 -

    function recursiveCheck(check, getResponse) {
      const result = getResponse()
      if (result === undefined)
        return "not found"
      else if (check(result))
        return "condition met"
      else
        return recursiveCheck(check, getResponse)
    }
    
    const output = recursiveCheck(myChcek, iter([{...}, {...}, ...]))
    
    console.log(output)
    

    在这种特殊情况下使用递归意味着您输入的大小将受到限制。如果你简单地使用for..of,你所有的问题都会消失-

    function iterativeCheck(check, iterable) {
      for (const result of iterable)
        if (check(result))
          return "condition met"
      return "not found"
    }
    
    const output = iterativeCheck(myCheck, [{...}, {...}, {...}, ...])
    
    console.log(output)
    

    另请参阅Symbol.asyncIterator,了解如何将这种方法用于异步迭代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2021-12-13
      • 1970-01-01
      • 2015-01-12
      • 2019-02-22
      • 1970-01-01
      相关资源
      最近更新 更多