【问题标题】:Why is indexOf returning -1 if no match has been found?如果没有找到匹配项,为什么 indexOf 返回 -1?
【发布时间】:2018-06-15 11:05:25
【问题描述】:

str.indexOf(searchValue[, fromIndex])

searchValue 第一次出现的索引,如果没有找到,则为 -1

-MDN web docs

如果在数组中找不到匹配项,为什么-1 会被.indexOf 选为返回值?

console.log([].indexOf()) // -> -1

不是更适合0吗?这是有道理的,因为确实有 0 匹配元素。这样我们就可以直接在条件语句中使用它,例如:

if( Array.indexOf(String) ) { ... }

代替

if( Array.indexOf(String) !== -1 ) { ... }

这是为什么呢?有什么特别的原因吗?我在 Java、C++ 和 C 中都看到过相同的情况。这是因为原生函数是如何设计的吗?

【问题讨论】:

  • 该函数返回第一个 index (即位置)找到该值的位置。请记住,在您提到的所有语言中,数组的第一个索引是 0
  • 数组的第一个索引是0:[1,2,3].indexOf(1) :0
  • 它显示的是位置,它不仅仅是一个是否存在的布尔值
  • 有一类问题几乎总是被否决或被阻止,那就是架构设计问题。我其实很喜欢建筑设计问题。通过理解这些,可以在计算机科学中获得很多见解。 Ivan 提出了一个非常基本的问题,但它讨论了原始 1 与 0 数组寻址,以及将错误代码折叠到结果中。我认为斯蒂芬劳赫阻止了这一点,以限制明显的答案。 FORTRAN、PASCAL 和 Lua 是 1 来源,但 C、python 和 Javascript 等较新的语言往往是 0 来源。

标签: javascript indexof


【解决方案1】:

用 0 代替不是更合适吗?

没有。索引从零开始。

var str = "ABC";
console.log(str[0]);
console.log(str.indexOf("A"));

(数组也是如此,尽管引用了字符串的文档,但您在示例中使用了数组)。

【讨论】:

  • 值得一提includes,因为它会给 OP 的预期输出?
  • 在编程中索引从零开始...除了极少数例外(例如 Visual Basic 的 Strings.InStr 方法,因为传统上在 BASIC 中索引从 1 开始)。
  • 你是对的,使用零会好得多,但是他们将不得不重新编写许多语言,因此它们不是基于零的,并且所有代码都是在过去 50 年中编写的年可能需要重写。所以现在改变它将是一大步。
【解决方案2】:

嗯。原因很简单。 indexOf 不返回元素的位置,如果它存在与否。此外,所有 (99%) 编程语言都被 0 索引,或者更好地说 stringsarrays 是 0 索引,这意味着第一个元素位于位置 0。

将位置视为数组开头元素的offset。所以第一个元素与数组开头的距离/偏移量是 0 :)

也许您正在寻找includes(),它会检查元素是否在数组中。

const arr=[1,2,3]
// classic
if (!arr.includes(4)) {
  console.log('4 does not exist (classic)')
}

// or short circuit

!arr.includes(4) && console.log('4 does not exist (short circuit)')

// conditional (ternary) operator

!arr.includes(4) ? console.log('4 does not exist (ternary)') : ""

观察

另外你不应该使用indexOf() 作为布尔条件,因为例如

let arr=['a','b','c']

arr.indexOf('a') ? console.log('true') : console.log('false')

在上面的例子中,indexOf(a) 返回它的位置0。在布尔条件下,0 被 javaScript 视为 false。所以它不会给你预期的结果。

【讨论】:

    【解决方案3】:

    其他人都在说同样的事情,但让我尝试另一种措辞的答案。

    在 Javascript 中,数组从元素 0 开始索引。因此,如果在开头找到的字符串 qas 则有效的返回值为 0。如果未找到字符串报告为 0,您将不知道它是在开始。 -1 绝不是字符串中某个位置的有效值。

    关于你的测试

    if( Array.indexOf(String) ) { ... }

    你可以改用

    if( 1+Array.indexOf(String) ) { ... }

    避免使用 !== -1 测试。

    一般来说,Array.indesOf() 的结果是重载的。结果包含函数结果和错误代码。这种重载允许在测试中直接使用函数调用。但是,请考虑,如果函数调用在 if 语句中,您可能需要再次调用该函数,这是效率损失。如果在您对结果进行分配然后测试结果之前,您的计算效率会更高。甚至没有内存成本,因为函数中的变量位于堆栈上,如果您将变量保持在本地,则函数返回时会清除该堆栈。

    返回包含成功/失败标志和结果的结构的函数是一种简洁的方法,可以概括可能失败的函数调用,并且是放置异常处理而不会使您的简单测试复杂化的方便位置想做。

    【讨论】:

      【解决方案4】:

      因为在几乎所有编程语言中,0 都是数组的第一个位置。

      【讨论】:

        【解决方案5】:

        indexOf() 为您提供数组中元素的位置,数组的有效索引从0, 1, ... 等开始直到array.length-1 所以如果indexOf() 将返回0 不存在元素然后这是不正确的,因为0 是一个有效的索引。因此使用了-1

        【讨论】:

          猜你喜欢
          • 2012-01-25
          • 2017-06-04
          • 1970-01-01
          • 1970-01-01
          • 2020-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多