2

使用 indexOf 时,我可以定位到第一次出现的位置:

例如:

a=[1,2,4,2];
b=a.indexOf(2);
alert(b) //returns 1

indexOf 是否有任何替代功能可以找到两个位置,或者我错过了什么?我正在寻找捷径。当然,我总是可以去写一个简单的外观来找到它。

4

4 回答 4

5

indexOf 接受第二个参数(起始索引)

所以a.indexOf(2,2)会给你3

概括地说,如果x = a.indexOf(2),那么下一个实例是a.indexOf(2, x+1)

于 2013-07-11T17:27:45.967 回答
3

一个循环:

function indexesOf(arr, target) {
    let index = [];
    // For each element, index pushed in index[]
    arr.forEach((el, i) => {
        if (el === target) index.push(i)
    });
    return index;
}
alert(indexesOf([1, 2, 4, 2], 2));  // -> 1, 3

有两个循环:

function indexesOf(arr, target) {
  // Map matching elements to their index, and others to null.
  return arr.map(function (el, i) { return (el === target) ? i : null; })
            // Throw out the nulls.
            .filter(function (x) { return x !== null; });
}

alert(indexesOf([1, 2, 4, 2], 2));  // -> 1, 3
于 2013-07-11T17:31:25.263 回答
1

当您使用最近的 ECMAScript 5 方法时,您可能需要考虑使用新的 Harmony 建议Array.map方法Array.filterObject.is

Javascript

var func = {}.is,
    is;

if (typeof func === "function") {
    is = func;
} else {
    is = function is(x, y) {
        if (x === y) {
            if (x === 0) {
                return 1 / x === 1 / y;
            }

            return true;
        }

        var x1 = x,
            y1 = y;

        return x !== x1 && y !== y1;
    };
}

function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }

    return array.map(function (element, index) {
        if (is(value, element)) {
            return index;
        }
    }).filter(function (element) {
        return typeof element === "number";
    });
}

var test = [1, 2, 4, 2];

console.log(indexesOf(test, 2));

输出

[1, 3] 

jsfiddle 上

更新:过去,当人们坚信“但这正是这些新方法的设计目的”时,我曾因使用循环而受到严厉批评。因此,我也将介绍替代的单循环解决方案。

ECMAScript 5Array.reduce

Javascript

function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }

    return array.reduce(function (previous, current, index) {
        if (is(value, current)) {
            previous.push(index);
        }

        return previous;
    }, []);
}

jsfiddle 上

ECMAScript 5Array.forEach

Javascript

function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }

    var indexes = [];

    array.forEach(function (element, index) {
        if (is(value, element)) {
            indexes.push(index);
        }
    });

    return indexes.
}

jsfiddle 上

ECMAScript 5Array.indexOf

注意:这个方法是找不到索引的 NaN

也可以反向使用Array.lastIndexOf和工作

Javascript

function indexesOf(array, value) {
    if (!Array.isArray(array)) {
        throw new TypeError("First attribute must be an array.");
    }

    var index = array.indexOf(value),
        indexes = [];

    while (index !== -1) {
        indexes.push(index);
        index = array.indexOf(value, index + 1);
    }

    return indexes;
}

jsfiddle 上

标准for

Javascript

function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }

    var indexes = [],
        length,
        index;

    for (index = 0, length = array.length; index < length; index += 1) {
        if (array.hasOwnProperty(index) && is(value, array[index])) {
            indexes.push(index);
        }
    }

    return indexes;
}

jsfiddle 上

标准while

Javascript

function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }

    var length = array.length,
        indexes = []
        index = 0;

    while (index < length) {
        if (array.hasOwnProperty(index) && is(value, array[index])) {
            indexes.push(index);
        }

        index += 1;
    }

    return indexes;
}

jsfiddle 上

标准for...in

注意:不建议这样做,但应该没问题。

为什么在数组迭代中使用“for...in”是个坏主意?

Javascript

function indexesOf(array, value) {
    if ({}.toString.call(array) !== "[object Array]") {
        throw new TypeError("First attribute must be an array.");
    }

    var indexes = [],
        prop;

    for (prop in array) {
        if (array.hasOwnProperty(prop) && is(+prop, prop >>> 0) && is(value, array[prop])) {
            indexes.push(+prop);
        }
    }

    return indexes;
}

jsfiddle 上

注意:这里的所有解决方案都处理密集和稀疏数组。

最后是一个比较所有这些解决方案的jsperf 。

于 2013-07-11T17:58:47.257 回答
0

lastIndexOf() 给出最后出现的索引。

但是,如果想要一个包含特定元素的所有出现的索引数组(在您的情况下为 2),则必须编写一个循环。

于 2013-07-11T17:29:45.603 回答