Advanced-Frontend / Daily-Interview-Question

我是依扬(木易杨),公众号「高级前端进阶」作者,每天搞定一道前端大厂面试题,祝大家天天进步,一年后会看到不一样的自己。

Home Page:https://muyiy.cn/question/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

第 151 题:用最简洁代码实现indexOf方法

libin1991 opened this issue · comments

image

image

字符串变为数组,用数组方法findIndex去查找。

commented
Object.prototype.sIndexOf = function (char) {
  const len = this.length
  for (let i = 0; i < len; i++) {
    if (this[i] === char) {
      return i
    }
  }
  return -1
}
_indexOf( str , arr ) {
  if(!arr.length) return;
  if(!arr && arr.length < 1) return;
  const toArrary = obj => [].slice.call(obj);
  let result = -1;
  Array.form 
    ? result = Array.from(arr).findIndex(el => el == str)
    : result = toArrary(arr).findIndex(el => el == str)
  return result;
} 
let strData = '123456'
let arrData = [1,2,3];
console.log(_indexOf(1,strData),'strData');
console.log(_indexOf(1,arrData),'arrData');
commented

能使用其它数组api?
能的话,嘿嘿嘿:

const indexOf = (arr, val) => {
  return arr.findIndex(item => item === val);
}
commented

这题考点在哪啊,没盖特到 ,难道是有什么特别6的写法吗

function _indexOf(str, reg, fromIndex = 0) { let index = fromIndex; const { length } = str; if (index <= 0) index = 0; if (index >= length) return -1; const arr = str.slice(fromIndex).split(reg); return arr.length > 1 ? arr[0].length + fromIndex : -1 }

看了一圈怎么没人考虑indexOf的第二个起始参数呢?

function indexOf(arr,target,start=0){
     if(start<0) start+=arr.length;
     if(start>=arr.length) return -1;
     for(let i=start;i<arr.length;++i){
        if(arr[i]===target) return i;
  }
  return -1;
}
function indexOf(str, a, start) {
    start = start == undefined ? 0 : start;
    for (var i = start; i < str.length; i++) {
        if (str[i] == a) {
            return i;
        }
    }
    return -1;
}

function indexOf(str, serchStr, index) {
if(index){
return str.substr(index,).match(serchStr)?str.substr(index,).match(serchStr).index + index :-1
}else{
return str.match(serchStr)?str.match(serchStr).index:-1
}
}

commented

Array.prototype.myIndexOf = function(item, start = 0) {
const length = this.length;
const startPos = start >= 0 ? start : length + start;
if (start >= length) return -1;
for (let i = startPos; i < length; i++) {
if (this[i] === item) return i;
}
return -1;
};

看了一圈怎么没人考虑indexOf的第二个起始参数呢?

因为大家都不咋用这个参数,想不起来了呗

Object.prototype.MyIndexOf = function(str, from=0){
    let data = this;
    let isArray = Array.isArray(data);
    let isString = Object.prototype.toString.call(data) == '[object String]';
    if (!isArray && !isString) throw new SyntaxError();
    let len = data.length;
    if(from >= len) return -1;
    for(var i = from; i <len; i++){
        if (isString){
            let strLen = str.length;
            if (data.substr(i, i+strLen) == str){
                return i;
            }
        }
        if (isArray && data[i] == str){
            return i;
       }
    }
    return -1;
}

commented

"hello world".indexOf('he') 有的写得只能匹配单个字符

commented
function indexOf(str, target){
  for(let i = 0; i < str.length; i ++){
    let j = 0;
    if(str[i] === target[j]){
     while(++j<target.length){if(str[i+j] !== target[j]) break;}
     if(j === target.length) {return i;}  
   }
  }
  return -1;
}

@ghost2113 substr应该换成substring吧

commented

// 暴力匹配 function ViolentMatch(s, p) { var i = 0, j = 0, pLen = p.length, sLen = s.length; while (i < sLen && j < pLen) { if (s[i++] != p[j++]) { i = i - (j - 2) - 1; j = 0; } } return j == pLen ? i - j : -1; }

commented
String.prototype.indexOFS = function (string, start = 0) {
  return this.substr(start).match(new RegExp(string)) ? (this.substr(start).match(new RegExp(string)).index + start) : -1
};
function _indexOf(string, target) {
	if (typeof string !== 'string') {
		throw new Error('string only');
	}
	let mt = string.match(new RegExp(target))
	return mt ? mt.index : -1;
}

使用正则 indexOf('/:>-|+?','/:>-|+?') 这个测试用例应该通不过

indexOf 字符串,数组也能用吧,

function indexOfTest(arrOrString, target, index = 0) {
    if(Array.isArray(arrOrString)) {
        for(let i = index; i < arrOrString.length; i++) {
            if(arrOrString[i] == target) {
                return i
            }
        }
        return -1;
    }
    // 字符串
    const newArr = arrOrString.split(target);
    if(newArr.length == 1) {
        return -1
    }
    let res = 0;
    for(let j = 0; j < newArr.length; j++) {
        if(newArr[j] == "" && index == 0) {
            return 0
        }
        if(res > index) {
            return res;
        }
        res += newArr[j].length || 1;
    }
    return res;
}
function formatIndexof(str, target, index) {
            let begin = index || 0;
            let end = str.length || 0;
            const tLen = target.length
            if (begin > end) {
                return -1;
            }
            if (tLen == 1 || Object.prototype.toString.call(str) === '[object Array]') {
                for (let i = begin; i < end; i++) {
                    if (str[i] === target) {
                        return i
                    }
                }

            } else if (tLen > 1) {
                for (let i = begin; i < end; i++) {

                    const temp = str.slice(i, tLen + i);

                    if (target === temp) {
                        return i
                    }
                }

            }
            return -1;

        }

@Zhou-Bill

function formatIndexof(str, target, index) {
            let begin = index;
            let end = str.length - 1 || 0;
            if (begin > end) {
                return -1;
            }
            for (let i = begin; i < end; i++) {
                if (str[i] === target) {
                    return i
                }
            }
            return -1;

        }

formatIndexof("test", "tes") 这样不是不行吗

function formatIndexof(str, target, index) {
            let begin = index;
            let end = str.length - 1 || 0;
            if (begin > end) {
                return -1;
            }
            for (let i = begin; i < end; i++) {
                if (str[i] === target) {
                    return i
                }
            }
            return -1;

        }

formatIndexof("test", "tes") 这样不是不行吗
是有这个问题 ,已经做出修改

好像没说是数组还是字符的indexOf

      function arrayIndexOf (array = [], item) {
        for (let i = 0; i < array.length; i++) {
          if (array[i] === item) {
            return i;
          }
        }
        return -1;
      }

      function stringIndexOf (str = '', subStr) {
        if (!subStr) return -1;
        for (let i = 0; i < str.length; i++) {
          if (str.substr(i, subStr.length) === subStr) {
            return i;
          }
        }
        return -1;
      }

for循环 这题好像没什么考的意义哦

这题考点在哪啊,没盖特到 ,难道是有什么特别6的写法吗

考点应该是对api的了解,比如入参(val,startIndex),还有返回值startIndex<0和startIndex>this.length,notFound等

const strings = 'abcd123fka'
String.prototype.indexOfFn = function(str, index = 0) {
  const string = this.substring(index)
  return string.split('').findIndex(item => item === str) + index
}
console.log(strings.indexOfFn('3'))
function indexOf(arr,target,start=0){
     if(start<0) start+=arr.length;
     if(start>=arr.length) return -1;
     for(let i=start;i<arr.length;++i){
        if(arr[i]===target) return i;
  }
  return -1;
}

indexOf可适用于数组和字符串,共同点是输入参数和返回值相同,不同点是,如果是字符串,那么输入的值会自动转化为string类型(如输入值为number类型时),而数组不会转换

例子:
const array = ["1",2,3,4];
const str = "123456";
array.indexOf("1"); // 0
array.indexOf(1); // -1
array.indexOf(2); // 1
str.indexOf(1); // 0 这里自动将number 类型的1转化为了string类型的 "1"
str.indexOf("1"); // 0

function indexOf(str, val){
    return str.indexOf(val);
}

如此简洁,敢问”还有谁?”

commented

简单写了一下

YuArtian/blog#21

commented

好像没说是数组还是字符的indexOf

      function arrayIndexOf (array = [], item) {
        for (let i = 0; i < array.length; i++) {
          if (array[i] === item) {
            return i;
          }
        }
        return -1;
      }

      function stringIndexOf (str = '', subStr) {
        if (!subStr) return -1;
        for (let i = 0; i < str.length; i++) {
          if (str.substr(i, subStr.length) === subStr) {
            return i;
          }
        }
        return -1;
      }

image

KMP 解法

这是一道LeetCode原题实现strStr

KMP 算法(Knuth-Morris-Pratt 算法)是一个著名的字符串匹配算法,使用空间换时间可以使得时间复杂度下降到$O(N)$。

代码

public class KMP {
    private int[][] dp;
    private String pattern;

    public KMP(String pattern) {
        this.pattern = pattern;
        int M = pattern.length();
        dp = new int[M][256];
        dp[0][pattern.charAt(0)] = 1;

        int X = 0;
        for (int j = 1; j < M; j++) {
            for (int c = 0; c < 256; c++) {
                dp[j][c] = dp[X][c];
            dp[j][pattern.charAt(j)] = j + 1;
            X = dp[X][pattern.charAt(j)];
        }
    }

    public int search(String str) {
        int M = pattern.length();
        int N = str.length();
        int j = 0;
        for (int i = 0; i < N; i++) {
            j = dp[j][str.charAt(i)];
            if (j == M) return i - M + 1;
        }
        return -1;
    }
}

复杂度分析

  • 时间复杂度:$O(N)$
  • 空间复杂度:$O(M)$

欢迎关注我的[LeetCode]题解(https://github.com/azl397985856/leetcode)

image

function indexof(str, sub, start=0){
    if(start<0) start = 0;
    if(sub===''&&start>=str.length) return str.length;
    if(sub!==''&&start>=str.length) return -1;
    const target = str.slice(start);
    return target.search(sub)+start;
}
function indexOf(arr,target,start=0){
     if(start<0) start+=arr.length;
     if(start>=arr.length) return -1;
     for(let i=start;i<arr.length;++i){
        if(arr[i]===target) return i;
  }
  return -1;
}

indexOf可适用于数组和字符串,共同点是输入参数和返回值相同,不同点是,如果是字符串,那么输入的值会自动转化为string类型(如输入值为number类型时),而数组不会转换

例子:
const array = ["1",2,3,4];
const str = "123456";
array.indexOf("1"); // 0
array.indexOf(1); // -1
array.indexOf(2); // 1
str.indexOf(1); // 0 这里自动将number 类型的1转化为了string类型的 "1"
str.indexOf("1"); // 0

let str = 'hello wrod'
str.indexOf(str,'ll')
直接凉 兄弟

commented
function indexOf(str, val){
    return str.indexOf(val);
}

如此简洁,敢问”还有谁?”

你赢了

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

更过编程算法题可见 JavaScript-Algorithms

function indexOf(str, a, start) {
    start = start == undefined ? 0 : start;
    for (var i = start; i < str.length; i++) {
        if (str[i] == a) {
            return i;
        }
    }
    return -1;
}

只是单字符的

Array.prototype.myIndexOf = function (value, fromIndex) {
const len = this.length
let index = -1
fromIndex = fromIndex === undefined ? 0 : fromIndex
if (fromIndex < 0) {
fromIndex = len + fromIndex;
fromIndex = fromIndex < 0 ? 0 : fromIndex;
}
for (let i = fromIndex; i < len; i++) {
if (this[i] === value) {
index = i;
break;
}
}
return index
}

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

更过编程算法题可见 JavaScript-Algorithms

赞,不过 感觉 SyntaxError 换成 TypeError 是不是更好一点

commented
function mockIndexOf(eles, target, startIndex = 0) {
  const dataType = Object.prototype.toString.call(eles);
  if (dataType === '[object Array]') {
    const len = eles.length;
    const _startIndex = startIndex >= 0 ? startIndex : startIndex + len;
    return eles.findIndex((v, index) => {
      return _startIndex <= index && v === target;
    });
  }
  if (dataType === '[object String]') {
    const len = eles.length;
    const _startIndex =
      startIndex >= 0 ? (startIndex < len ? startIndex : len) : 0;
    const result = eles.substr(_startIndex).match(target);
    console.log(result, eles.substr(startIndex), target);
    return result ? result.index + _startIndex : -1;
  }
  throw new Error('第一个参数请传入数组或者字符串');
}

mockIndexOf('dsafsa', 'sa')' // 1
mockIndexOf('dsafsa', 'sf')' // -1
commented
  1. 题目中的“最简洁”感觉是特意用来误导人的,因为此方法有一些难以一下子想到的需要考虑的点
  2. 数组对象的此原型方法和字符串对象的此原型方法需要考虑的点不一样
  3. Mdn 文档上有数组原型方法 indexOf 的官方解法 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

兼容实现字符串和数组的 indexOf,针对字符串处理方式不一样:

export function indexOf(arr: string, item: string, fromIndex ? : number): number;
export function indexOf(arr: Array < any > , item: any, fromIndex ? : number): number;
export function indexOf(arr: any, item: any, fromIndex: number = 0) {
    let index = -1;
    if (typeof arr === 'string') {
        const m = item.length
        for (let i = fromIndex, len = arr.length - m; i < len; i++) {
            if (item === arr.substr(i, m)) {
                index = i;
                break;
            }
        }
    } else if (arr instanceof Array) {
        for (let i = fromIndex, len = arr.length; i < len; i++) {
            if (item === arr[i]) {
                index = i;
                break;
            }
        }
    }
    return index;
}
commented
/**
 * 字符串
 * @param str
 * @param target
 * @param start
 * @returns {number|*}
 */
function strIndexOf(str, target, start = 0){
  if (start > str.length) {
    return -1;
  }

  if (start < 0) {
    start = 0;
  }

  for (let i = start; i < str.length; i++) {
    let current = str.substring(i, i + target.length);

    if (current === target) {
      return i;
    }
  }

  return -1;
}
function indexOf(a, b){
  var index = a.split(b)[0].length;
  return  index === a.length ? -1 : index;
}

var a = 'abcbbcddc';
var b = 'bb';
indexOf(a, b); // 3
indexOf(a, '1'); // -1
// 使用startsWith
function indexOf(src: string, slice: string): number {
  const _indexOf = (src: string, slice: string, index: number): number => {
    if (slice.length === 0 || src.length < slice.length) return -1
    return src.startsWith(slice) ? index : _indexOf(src.slice(1), slice, index + 1)
  }
  return _indexOf(src, slice, 0)
}

// 循环版本
function indexOf2(src: string, slice: string): number {
  for (let i = 0; i < src.length && (src.length - i) >= slice.length; ++i) {
    if (src.startsWith(slice, i)) return i
  }
  return -1;
}

const a = 'abcdefghijkl'
const b = 'ghi'
const c = '123'
console.log(indexOf(a, b))  // 6
console.log(indexOf(a, c))  // -1
commented

'123'.search(x)

commented

先说下思路吧,比较笨,哈哈

  • 如果是数组,就直接比较,不难。。
  • 如果是字符串,这种abccccabcaaa这种比较,就是从第一个开始,每三个长度为一段进行比较
    abc比较ccc, abc比较cca, abc比较cab... 比较笨吧, 可能性能比较差,但是好理解。。
  function findIndex(key, obj) {
    console.log(`查找的对象${obj}`, `----查找的键值${key}`)
    let arr = []
    let index = -1 //最后返回查找到的索引
    /**********************如果是数组***********************/
    if (obj instanceof Array) {
      arr = obj
      arr.some((i, indexA) => {
        if (i == key) {
          index = indexA
          return true
        }
      })
    }
    /**********************如果是字符串***********************/
    else if (typeof (obj) === 'string') {
      arr = obj.split('')
      let keyLen = key.length
      for(let i=0;i<=arr.length-keyLen;i++){
        if(key === obj.substring(i, i+keyLen)){
          index = i
        }
      }
    } else {
      return '不符合数据格式'
    }
    return index
  }
  console.log(31, findIndex('g', 'abcdefg'))
  console.log(32, findIndex(22, [22,33,444]))

实现

/**
 * 
 * @param {string} p 
 */
function buildNext(p) {
  const m = p.length
  const N = []
  let t = N[0] = -1
  let j = 0
  while (j < m -1) {
    if (0 > t || p[j] === p[t]) {
      j++
      t++
      // 根据已知信息如果p[j] !== t[i] 如果p[j] === p[t]则p[t]必然失配t[i]所以这次比较可以优化
      N[j] = p[j] !== p[t] ? t : N[t]
    } else {
      t = N[t]
    }
  }
  return N
}
/**
 * kmp字符串模式匹配
 * @param {string} t 
 * @param {string} p 
 */
function match(t, p) {
  let N = buildNext(p)
  let i = 0
  let j = 0
  const n = t.length
  const m = p.length
  while(j < m && i < n) {
    if (0 > j || t[i] === p[j]) {
      i++
      j++
    } else {
      j = N[j]
    }
  }
  return j === m ? i - j : -1
}

export function indexOf(s, fromIndex = 0) {
  fromIndex = 0 > fromIndex  
    ? this.length + fromIndex > 0
      ? this.length + fromIndex
      : 0
    : fromIndex
  console.log(fromIndex)
  const i = match(this.slice(fromIndex), s) 
  return i > 0 ? fromIndex + i : i
}

测试

import { indexOf} from '@/dayily-interview/kmp'

describe('kmp.js', () => {
  it('match success',() => {
    expect(indexOf.call('test success', 'c')).toBe(7)
  })
  it('match fail',() => {
    expect(indexOf.call('test success', 'z')).toBe(-1)
  })
  it('match success with from index', () => {
    expect(indexOf.call('test success', 's', 3)).toBe(5)
  })
  it('match fail with from index', () => {
    expect(indexOf.call('test success', 't', 4)).toBe(-1)
  })
  it('match success with complex', () => {
    expect(indexOf.call('test success', 'ucce', 3)).toBe(6)
  })
  it('match with negative from index', () => {
    expect(indexOf.call('test success', 'ucce', -16)).toBe(6)
  })
  it('match with negative from index', () => {
    expect(indexOf.call('test success', 'ss', -1)).toBe(-1)
  })
  it('match with negative from index', () => {
    expect(indexOf.call('test success', 'ss', -2)).toBe(10)
  })
  it('match with zero from index', () => {
    expect(indexOf.call('test success', 'ss', 0)).toBe(10)
  })
})

思路一: 利用正则比对当前字符串找出位置
function indexOf1(str,val){
const reg = new RegExp(${val},'gi');
const result = reg.exec(str);
return result?result.index:-1;
}
思路二: 利用字符串截取循环找到符合截取值的位置
function indexOf2(str,val){
const sl = str.length;
const vl = val.length;
for(var i=0;i<=sl-vl;i++){
if(str.slice(i,vl+i)===val){
return i;
}
}
return -1;
}

class myString extends String {
  myIndexOf(str: string) {
    const O = Object(this);
    const reg = new RegExp(str, 'g');
    const res = reg.exec(O);
    if (res) {
      return res.index;
    }
    return -1;
  }
}

const stringTest = new myString('abcdefg');

console.log(stringTest.myIndexOf('23'));
console.log(stringTest.myIndexOf('cde'));

export {};
commented
Object.prototype.sIndexOf = function (char) {
  const len = this.length
  for (let i = 0; i < len; i++) {
    if (this[i] === char) {
      return i
    }
  }
  return -1
}

不通过 'CDEFGAB'.sIndexOf('EF') // log -1

commented
//js 实现indexof
Array.prototype._indexOf=function(res,fromIndex){
  let len = this.length;

  if(len === 0) return [];
  if(fromIndex > len){
    fromIndex = len;
  }
  if(fromIndex <= 0){
    fromIndex = 0
  }
  for(let i = fromIndex; i < len; i++){
    if(this[i] === res){
      return i;
    }
  }
  return -1;
}
String.prototype.myIndexOf = function (str, fromIndex = 0) {
  const arr = this.slice(fromIndex).split(str);
  return arr.length === 1 ? -1 : arr[0].length + fromIndex;
};
console.log("asdfghjkl".myIndexOf("fg", 2));
console.log("asdfghjkl".indexOf("fg", 2));

Array.prototype.myIndexOf = function (str, fromIndex = 0) {
  const arr = this.slice(fromIndex).join("").split(str);
  return arr.length === 1 ? -1 : arr[0].length + fromIndex;
};
console.log(["aa", "ss", "dd", "ff", "gg", "hh", "jj", "kk", "ll"].myIndexOf("ff", 4));
console.log(["aa", "ss", "dd", "ff", "gg", "hh", "jj", "kk", "ll"].indexOf("ff", 4));

commented

看了下评论区发现,此题说用最简单代码实现,故意误导了大家往简单的想...
其实还应考虑以下几点:
1.String.prototype.indexOf 和 Array.prototype.indexOf
2.indexOf第二个可选参数 fromIndex
3.字符串indexOf可以是连续的一段,例如'astring'.indexOf('ing'),实现时无法像处理数组一样 直接拆成一个个字符比较,而应该拆成多段(有多种组合)比较。

/**
 * @param {*} item
 * @param {Number} fromIndex
 */
function indexOf(item, fromIndex = 0) {
  if (fromIndex < 0) fromIndex = 0
  if (fromIndex >= this.length) return -1

  for (let i = fromIndex; i < this.length; i += 1) {
    if (Array.isArray(this)) {
      if (this[i] === item) return i
    } else if (typeof this === 'string') {
      for (let j = i; j < this.length; j += 1) {
        const sub = this.substring(i, j + 1)
        if (sub === item) return i
      }
    }
  }
  return -1
}

// eslint-disable-next-line no-extend-native
Array.prototype.myIndexOf = indexOf
// eslint-disable-next-line no-extend-native
String.prototype.myIndexOf = indexOf

/**
 * test
 */
const arrRes = ['q', 'w', 'e', 'r'].myIndexOf('e', 1)
console.log('arrRes: ', arrRes)
const strRes = 'abcdefgkdeg'.myIndexOf('deg')
console.log('strRes: ', strRes)
Array.prototype.myIndexOf = function(target,fromIndex){
    if(!Array.isArray(arr)){
        throw new Error('this is not a array')
    }
    fromIndex = fromIndex || 0
    for(let i=0;i<=this.length-1;i++){
        if(this[i] === target && i>=fromIndex){
            return i
        }
    }
    return -1
}   
String.prototype.indexOf = function (search, fromIndex = 0) {
	if (fromIndex < 0) fromIndex = 0;
	if (fromIndex >= this.length) return -1;
	let str = this;
	let reg = RegExp(`(?<=.{${fromIndex}})(${search})`);
	let result = reg.exec(str);
	return result ? result.index : -1;
};

数组,感觉这题是考indexOf的定义,fromIndex的各种取值对结果的影响

Array.prototype.indexOf = function (search, fromIndex = 0) {
	const arrLen = this.length;
	if (fromIndex >= arrLen) return -1;
	if (fromIndex < 0) {
		fromIndex = arrLen + fromIndex;
	}
	for (let i = fromIndex; i < arrLen; i++) {
		if (i < 0) {
			i = 0;
			continue;
		}
		if (search == this[i]) {
			return i;
		}
	}
	return -1;
};
function myIndexOf(source, target, start = 0) {
    if (Array.isArray(source)) {
      let res = -1;
      for (let i = start; i < source.length; i++) {
        if (source[i] === target) return res = i;
      }
    }
    if (typeof source === 'string') {
      const reg = new RegExp(target, 'g');
      reg.lastIndex = start;
      const result = reg.exec(source);
      return result ? result.index : -1;
    }
  }
    Array.prototype._indexOf = function (val, start) {
      if (typeof start !== "number") start = 0; //start 非数字
      if (start < 0) start = start + this.length //start 小于零
      const index = this.slice(start).findIndex((item) => item === val);
      return index > -1 ? index + start : -1
    }

    String.prototype._indexOf = function (val, start) {
      if (typeof start !== "number") start = 0;
      start = Math.min(Math.max(0, start), this.length) // start大于等于0小于字符串的长度
      if (val === '') return start; // val为空字符串返回开始的位置
      const reg = new RegExp(val);
      const res = this.slice(start).match(reg);
      return res ? res.index + start : -1
    }
String.prototype._indexOf = function (val, start) {
      if (typeof start !== "number") start = 0; // start非数字
      start = Math.min(Math.max(0, start), this.length) // start大于等于0小于字符串的长度
      if (val === '') return start; // val为空字符串返回开始的位置
      const arr = this.slice(start).split(val);
      return arr.length >= 2 ? arr[0].length + start : -1 // 分割后的数组大于2就说存在,并且第一个值的长度加开始位置就是val的index
    }

indexof如果像楼上们那样写的话,速度太慢了,最简单的就是直接用indexof,如果是要实现他,当然是用kmp算法,速度最快。
https://github.com/chengruixin/rax-search/blob/main/src/exactMatch/patternFinder.ts

function isNumber(number) {
  return Object.prototype.toString.call(number) == '[object Number]'
}
function isString(string) {
  return Object.prototype.toString.call(string) == '[object String]'
}
function isArray(array) {
  return Object.prototype.toString.call(array) == '[object Array]'
}

function myIndexOf(target, searchVal,  fromIndex = 0) {
  // 非字符串和非数组抛出异常
  if(!isString(target) && !isArray(target)) {
    throw new TypeError(target + '.indexOf is not a function')
  }
  let type = isString(target) ? 'string' : 'array'
  let sLen = String(searchVal).length;
  let tLen = target.length;
  
  if(isNumber(fromIndex) && target.length < fromIndex) {
    return -1
  }
  for (let i = 0; i < tLen; i++) {
    if((type == 'string' && target.substr(i, sLen) == searchVal) || (type == 'array' && target[i] == searchVal)) {
      return i;
    }
  }
  return -1
}

console.log(myIndexOf(['45','4587','89123','89'], '89', 3));
commented

const NOT_INCLUDE = -1;

String.prototype.indexOf = function(string, start = 0) {
if(typeof this !== 'string') throw new SyntaxError('SyntaxError, needs a string');
const reg = new RegExp(${string}, 'ig');
reg.lastIndex = start;
const result = reg.exec(this);
return result?.index ?? NOT_INCLUDE;
}

Array.prototype.indexOf = function(item, start = 0) {
if(!item) return NOT_INCLUDE;
if(Array.isArray(this)) throw new SyntaxError('syntax error, needs an array!');
for (let i = start; i < this.length; i++)

return NOT_INCLUDE;

}

Array.prototype._indexOf = function (searchElement, fromIndex = 0) {
  if (typeof fromIndex !== 'number') {
    fromIndex = 0;
  }
  if (fromIndex < 0) {
    fromIndex += this.length;
  }

  for (let i = fromIndex; i < this.length; i++) {
    if (this[i] === searchElement) return i;
  }
  return -1;
};
const str = 'helo world, nice to meet you!';

String.prototype.indexOf1 = function (target, start = 0) {
    if (typeof target !== 'string') {
        throw new Error('please enter string type value!');
    }
    const str = this;
    const len = str.length;
    const targetLen = target.length;
    let j = 0;

    for (let i = start; i < len; i++) {
        if (target[j] === str[i]) {
            j++;
            if (j === targetLen) {
                return i - targetLen + 1;
            }
        } else {
            j = 0;
        }
    }

    return -1;
}

console.log(str.indexOf1('e', 2)); // 15
console.log(str.indexOf1('h')); // 0
console.log(str.indexOf1('!')); // 28
console.log(str.indexOf1('world'));// 5
console.log(str.indexOf1('#')); // -1

commented
function indexOf(self, target, startIdx = 0) {
  if (startIdx >= self.length) return -1;

  let _startIdx = startIdx;
  const isArray = Array.isArray(self);

  if (_startIdx < 0) {
    _startIdx = isArray ? Math.max(0, _startIdx + self.length) : 0;
  }

  if (isArray) {
    for (let i = _startIdx; i < self.length; i++) {
      if (self[i] === target) return i;
    }

    return -1;
  }

  const regex = new RegExp(target, 'ig');

  regex.lastIndex = _startIdx;

  return regex.exec(self)?.index ?? -1
}
      const a = "abcdefg", b = "efg";
      const diff = a.length - b.length;
      for (let i = 0; i <= diff; i++) {
        if (a.slice(i, i + b.length) === b) {
          return i;
        }
      }
      return -1;