sisterAn / JavaScript-Algorithms

基础理论+JS框架应用+实践,从0到1构建整个前端算法体系
5.51k stars 634 forks source link

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

Open sisterAn opened 4 years ago

sisterAn commented 4 years ago

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 类型可以一次匹配多个字符)

plane-hjh commented 4 years ago

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;
}
JerryWen1994 commented 4 years ago

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;

plane-hjh commented 4 years ago

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 是字符串为什么不对,方便解释一下吗

0undefined0 commented 4 years ago

日复一日默写代码 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; }

JerryWen1994 commented 4 years ago

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')

plane-hjh commented 4 years ago

indexOf('abcd', 'cd')

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

xllpiupiu commented 3 years ago
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'))
eeve commented 3 years ago

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

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