从递归indexOf返回正确的值

问题描述

我已经编写了一个递归函数来模仿JavaScript中的.indexOf。

单步调试器时,除数组中不存在currentTexture === 1 参数外,其他所有操作均按预期进行。在item时触发停止条件,但随后调用栈展开并返回数组的总长度。

如果arr.length === 0不存在,它应该返回item

我是递归的新手,并认为我可能缺少逻辑。任何帮助表示赞赏。

-1

解决方法

数学归纳法可以指导您的程序。编号的步骤与程序注释中的编号行相对应-

  1. 如果位置pos在数组a的边界之外,则返回-1
  2. (归纳)位置是有界的。如果a[pos]与查询q相匹配,则返回pos
  3. (归纳)位置在范围内,a[pos]与查询不匹配。返回递归结果。

注意步骤的顺序很重要。例如,在检查a[pos]是否超出范围(步骤1)之前,我们不想尝试读取pos(步骤2)!

const search = (a,q,pos = 0) =>
  pos >= a.length
    ? -1                // 1
: a[pos] === q
    ? pos               // 2
: search(a,pos + 1) // 3

console.log(search(["a","b","c","d"],"c")) // 2
console.log(search(["a","z")) // -1

如果需要,可以将search设为高阶函数-

const search = (a,f,pos = 0) =>
  pos >= a.length
    ? -1
: Boolean(f(a[pos]))
    ? pos
: search(a,pos + 1)

console.log(search(["a",v => v === "c")) // 2
console.log(search(["a",v => v > "a"))   // 1
console.log(search(["a",v => v > "z"))   // -1


当我们仅使用两个参数调用pos时,您是否注意到第三个参数search是如何分配给默认值的,所以值为0 ?

search([ 4,99,5,8,1,9,11 ],5) // pos = 0
// => 2

pos=3开始,找到5的第一个位置也许很有用-

search([ 4,3) // third argument; pos = 3
// => 5

但是也许您不希望函数中的第三个参数。在此修改中,loop与我们的第一个函数具有相同的逻辑。 searchloop-

的简单包装

function search(a,q)
{ function loop(pos)
  { return pos >= a.length
      ? -1
    : a[pos] === q
      ? pos
    : loop(pos + 1)
  }
  return loop(0)
}

console.log(search(["a","z")) // -1

通过此更改,search仅响应两个参数-

search([ 4,3) // third argument ignored
// => 2
,

如果结果是整数(0或更大),则仅将1加到递归调用中;否则将其加1。如果结果为-1,则仅返回-1:

function search(arr,item) {
    if (arr[0] === item) {
        return 0;
    }

    if (arr.length === 0) {
        return -1;
    }

    const result = search(arr.slice(1),item);
    return result === -1 ? -1 : result + 1;
}

function search(arr,item);
    return result === -1 ? -1 : result + 1;
}

console.log(
  search([1,2,3,4],3),search([1,-333),);

,

我会将计数传递给递归调用。

此外,您的转义子句应该放在第一位。在JS中无关紧要,但是arr[0] === item在数组中没有任何内容时毫无意义。

function search(arr,item,count = 0) {
  if (arr.length === 0) {
    return -1;
  }
  
  if (arr[0] === item) {
    return count;
  }

  return search(arr.slice(1),count + 1);
}

console.log(
  search([1,);


实际上,由于.slice(1)可以用作索引,因此您无需使用count就可以做到这一点。

function search(arr,count = 0) {
  if (arr.length === count) {
    return -1;
  }
  
  if (arr[count] === item) {
    return count;
  }

  return search(arr,);