Skip to content

编程题:用最简洁代码实现 indexOf 方法 #58

Open

Description

@sisterAn

indexOf 有两种:

String.prototype.indexOf()

返回从 fromIndex 处开始搜索第一次出现的指定值的索引,如果未找到,返回 -1

str.indexOf(searchValue [, fromIndex])
// fromIndex 默认值为 0

Array.prototype.indexOf()

返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回 -1

arr.indexOf(searchElement[, fromIndex])

解答

String.prototype.indexOf()

解题思路:正则,字符串匹配

function sIndexOf(str, searchStr, fromIndex = 0){
    var regex = new RegExp(`${searchStr}`, 'ig')
    regex.lastIndex = fromIndex
    var result = regex.exec(str)
    return result ? result.index : -1
}

// 测试
var paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?'
var searchTerm = 'dog'
// 测试一:不设置 fromIndex
console.log(sIndexOf(paragraph, searchTerm))
// 40
console.log(paragraph.indexOf(searchTerm));
// 40
// 测试二:设置 fromIndex
console.log(sIndexOf(paragraph, searchTerm, 41))
// 52
console.log(paragraph.indexOf(searchTerm, 41));
// 52

测试成功

Array.prototype.indexOf()

解题思路:遍历匹配

function aIndexOf(arr, elem, fromIndex = 0){
    if(!elem) return -1
    for(let i = fromIndex; i < arr.length; i++) {
        if(arr[i] === elem) return i
    }
    return -1
}

// 测试
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison']
// 测试一:不设置 fromIndex
console.log(aIndexOf(beasts, 'bison'))
// 1
console.log(beasts.indexOf('bison'))
// 1
// 测试二:设置 fromIndex
console.log(aIndexOf(beasts, 'bison', 2))
// 4
console.log(beasts.indexOf('bison', 2))
// 4

测试成功

总结一下
function indexOf(items, item, fromIndex = 0) {
    let isArray = Array.isArray(items);
    let isString = Object.prototype.toString.call(items) == '[object String]';
    if (!isArray && !isString) throw new SyntaxError();
    if(isArray) return sIndexOf(items, item, fromIndex)
    else return aIndexOf(items, item, fromIndex)
}

你也可以尝试使用遍历匹配法解决 sIndexOf 问题(正则更简洁),这里不做介绍(和 aIndexOf 差不多的套路,不同的是,String 类型可以一次匹配多个字符)

Activity

  1. plane-hjh commented on Jun 2, 2020

    @plane-hjh

    str.indexOf(searchValue [, fromIndex])

    searchValue:要被查找的字符串值,默认 undefined

    fromIndex: 可选值。数字表示开始查找的位置。可以是任意整数,默认值为 0。如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和str.length 开始。

    参考出处:indexOf()

    解法一,正则

    function indexOf(str, a, start = 0) {
       if(start<0) start+=str.length;
       if(start>=str.length) return -1;
    
       const reg = new RegExp(`${a}`, 'gi')
       reg.lastIndex = start
       const result = reg.exec(str)
       return result ? result.index : -1
    }

    解法二,遍历

    function indexOf(str, a, start = 0) {
        if(start<0) start+=str.length;
        if(start>=str.length) return -1;
    
        for (let i = start, len = str.length; i < len; i++) {
            if (str.slice(i, i+a.length) == a) return i;
        }
        return -1;
    }
  2. JerryWen1994 commented on Jun 2, 2020

    @JerryWen1994

    str.indexOf(searchValue [, fromIndex])

    searchValue:要被查找的字符串值,默认 undefined

    fromIndex: 可选值。数字表示开始查找的位置。可以是任意整数,默认值为 0。如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和str.length 开始。

    参考出处:indexOf()

    解法一,正则

    function indexOf(str, a, start = 0) {
       if(start<0) start+=str.length;
       if(start>=str.length) return -1;
    
       const reg = new RegExp(`${a}`, 'gi')
       reg.lastIndex = start
       const result = reg.exec(str)
       return result ? result.index : -1
    }

    解法二,遍历

    function indexOf(str, a, start = 0) {
        if(start<0) start+=str.length;
        if(start>=str.length) return -1;
    
        for (let i = start, len = str.length; i < len; i++) {
            if (str[i] == a) return i;
        }
        return -1;
    }

    遍历的时候不应该是 if (str[i] == a) return i;,如果a是字符串的话就不对了,应该是 if (str.slice(i, i+a.length) == a) return i;

  3. plane-hjh commented on Jun 2, 2020

    @plane-hjh

    str.indexOf(searchValue [, fromIndex])
    searchValue:要被查找的字符串值,默认 undefined
    fromIndex: 可选值。数字表示开始查找的位置。可以是任意整数,默认值为 0。如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和str.length 开始。
    参考出处:indexOf()

    解法一,正则

    function indexOf(str, a, start = 0) {
       if(start<0) start+=str.length;
       if(start>=str.length) return -1;
    
       const reg = new RegExp(`${a}`, 'gi')
       reg.lastIndex = start
       const result = reg.exec(str)
       return result ? result.index : -1
    }

    解法二,遍历

    function indexOf(str, a, start = 0) {
        if(start<0) start+=str.length;
        if(start>=str.length) return -1;
    
        for (let i = start, len = str.length; i < len; i++) {
            if (str[i] == a) return i;
        }
        return -1;
    }

    遍历的时候不应该是 if (str[i] == a) return i;,如果a是字符串的话就不对了,应该是 if (str.slice(i, i+a.length) == a) return i;

    @597796340 如果 a 是字符串的话就不对了。这个 a 是字符串为什么不对,方便解释一下吗

  4. 0undefined0 commented on Jun 2, 2020

    @0undefined0

    日复一日默写代码
    function indexOf(str, a, start = 0) {
    if (start < 0) {
    start += str.length;
    }
    if (start >= str.length) return -1;
    for (let i = start, len = str.length; i < len; i++) {
    if (str[i] === a) { return i; }
    }
    return -1;
    }

  5. JerryWen1994 commented on Jun 2, 2020

    @JerryWen1994

    str.indexOf(searchValue [, fromIndex])
    searchValue:要被查找的字符串值,默认 undefined
    fromIndex: 可选值。数字表示开始查找的位置。可以是任意整数,默认值为 0。如果 fromIndex 的值小于 0,或者大于 str.length ,那么查找分别从 0 和str.length 开始。
    参考出处:indexOf()

    解法一,正则

    function indexOf(str, a, start = 0) {
       if(start<0) start+=str.length;
       if(start>=str.length) return -1;
    
       const reg = new RegExp(`${a}`, 'gi')
       reg.lastIndex = start
       const result = reg.exec(str)
       return result ? result.index : -1
    }

    解法二,遍历

    function indexOf(str, a, start = 0) {
        if(start<0) start+=str.length;
        if(start>=str.length) return -1;
    
        for (let i = start, len = str.length; i < len; i++) {
            if (str[i] == a) return i;
        }
        return -1;
    }

    遍历的时候不应该是 if (str[i] == a) return i;,如果a是字符串的话就不对了,应该是 if (str.slice(i, i+a.length) == a) return i;

    @597796340 如果 a 是字符串的话就不对了。这个 a 是字符串为什么不对,方便解释一下吗

    说错了,应该是说如果a是单字符的话就不对,indexOf('abcd', 'cd')

  6. plane-hjh commented on Jun 2, 2020

    @plane-hjh

    indexOf('abcd', 'cd')

    @597796340 哈哈哈哈明白了。应该是 a 是多字符的时候。多谢指出哈,已经修改啦

  7. xllpiupiu commented on Oct 2, 2021

    @xllpiupiu
    let str = 'hello world ,I am ok';
    /**
     * 正则方法实现
     * @param {*} searchStr 
     * @param {*} start 
     * @returns 
     */
    String.prototype.myindexOf=function(searchStr, start=0){
        if (start < 0) start += this.length
        if (start >= this.length) return -1
        const reg = new RegExp(`${searchStr}`, 'ig')
        reg.lastIndex = start//确定匹配起始位置
        let res = reg.exec(this)
        return res ? res.index : -1
    }
    console.log(str.myindexOf('world',7))
    /**
     * 2. 遍历字符串
     */
    String.prototype._indexOf = function(searchStr,start=0) {
        if(start<0) start+=this.length
        if(start>this.length-1) return -1
        for(let i=start;i<this.length;i++) {
            if(this.slice(i,i+searchStr.length)===searchStr) return i
        }
        return -1
    }
    console.log(str._indexOf('I'))
  8. eeve commented on Nov 17, 2021

    @eeve

    正则方法随便写两个就是错的,不要误人子弟

    sIndexOf('sss\^asdsad', '^')
    0
    
    'sss\^asdsad'.indexOf('^')
    3
    
    sIndexOf('sss$asdsad', '$')
    10
    
    'sss$asdsad'.indexOf('$')
    3
    
    sIndexOf('sss[$asdsad', '[')
    Uncaught SyntaxError: Invalid regular expression: /[/: Unterminated character class
    
    'sss[$asdsad'.indexOf('[')
    3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions