JS & jQuery: inArray () и indexOf () не работают должным образом, если индексы являются строками? - PullRequest
0 голосов
/ 21 ноября 2010

У меня есть такой массив:

var arr = [];
arr['A string'] = '123';
arr['Another string'] = '456';

и я пытаюсь найти индекс '123' или '456'.

Оба:

var string = $.inArray('123', arr)

и

var string = arr.indexOf('123')

дают мне -1.Можно ли заставить его работать, когда индексы являются строками?

Ответы [ 2 ]

3 голосов
/ 21 ноября 2010

Как и все методы Array и свойство length, метод indexOf объекта Array учитывает только числовые свойства массива.Это свойства, имена которых являются целыми числами без знака.Чтобы проверить наличие свойства с определенным значением, вы можете сделать что-то подобное для любого объекта, включая массивы.Нет никакой гарантии относительно порядка перечисления имен свойств, поэтому, если существует более одного свойства с определенным значением, вы не можете быть уверены, какое свойство вы получите:

function findPropertyWithValue(obj, val) {
    for (var i in obj) {
        if (obj.hasOwnProperty(i) && obj[i] === val) {
            return i;
        }
    }
    return null;
}

var arr = [];
arr['A string'] = '123';
arr['Another string'] = '456';
alert(findPropertyWithValue(arr, "123")); // 'A string'

Обратите внимание, что, поскольку все свойстваимена, в том числе числовые, преобразуются в строки, свойства массива можно назначать с помощью строк:

var arr = [];
arr["1"] = "foo";
arr[3] = "bar"
arr.indexOf("foo"); // 1
arr.indexOf("bar"); // 3
3 голосов
/ 21 ноября 2010

Проблема в том, что вы используете массив JavaScript в качестве ассоциативного массива, что-то, что не является . Индексы массива JavaScript представляют собой 32-разрядные целые числа без знака, и поэтому вы не можете использовать * строки **. Вы могли бы использовать массив как

// I'm guessing that you meant to give numerical and not string values
var arr = [123, 456];

или используйте объект

var obj = { 
    'A string' : 123,
    'Another string' : 456
};

Обратите внимание, что при использовании объекта 'A string' и 'Another string' являются свойствами объекта obj и не могут быть проиндексированы, как значения в массиве. Вы можете проверить, что объект имеет свойство несколькими способами, одним из которых будет использование hasOwnProperty

if (obj.hasOwnProperty('A string')) {
    // if obj has property 'A string' as a direct property
}

другой использовал бы ключевое слово in

if ('A string' in obj) {
    // if obj has a property 'A string' as a property (could be an inherited property too)
}

**, если строка не является строковым представлением 32-битного целого без знака, как указывает Тим , но я думаю, что будет справедливо сказать, что многие разработчики JavaScript сказали бы, что для ясности придерживайтесь целых . *

...