Самый быстрый способ определить, находится ли значение в группе значений в Javascript
У меня есть группа строк в Javascript, и мне нужно написать функцию, которая определяет, принадлежит ли к этой группе другая конкретная строка.
Каков самый быстрый способ достичь этого? Можно ли положить группу значений в массив, а затем написать функцию, которая выполняет поиск по массиву?
Я думаю, что если я сохраню значения отсортированы и выполняю двоичный поиск, он должен работать достаточно быстро. Или есть какой-то другой умный способ сделать это, что может работать быстрее?
Ответы
Ответ 1
Используйте хеш-таблицу и выполните следующее:
// Initialise the set
mySet = {};
// Add to the set
mySet["some string value"] = true;
...
// Test if a value is in the set:
if (testValue in mySet) {
alert(testValue + " is in the set");
} else {
alert(testValue + " is not in the set");
}
Ответ 2
Вы можете использовать такой объект:
// prepare a mock-up object
setOfValues = {};
for (var i = 0; i < 100; i++)
setOfValues["example value " + i] = true;
// check for existence
if (setOfValues["example value 99"]); // true
if (setOfValues["example value 101"]); // undefined, essentially: false
Это использует тот факт, что объекты реализованы как ассоциативные массивы. Насколько быстро это зависит от ваших данных и реализации механизма JavaScript, но вы можете легко выполнить некоторые тесты производительности для сравнения с другими вариантами его выполнения.
Если значение может иметь место несколько раз в вашем наборе, а "как часто" важно для вас, вы также можете использовать увеличивающееся число вместо логического, используемого для моего примера.
Ответ 3
Комментарий к вышеупомянутым хэш-решениям.
Фактически {} создает объект (также упоминавшийся выше), который может привести к некоторым побочным эффектам.
Один из них заключается в том, что ваш "хэш" уже предварительно заполнен объектными методами по умолчанию.
Итак "toString" in setOfValues
будет true
(по крайней мере, в Firefox).
Вы можете добавить другой символ, например. "" к вашим строкам, чтобы обойти эту проблему или использовать объект Hash, предоставленный библиотекой "prototype".
Ответ 4
Наткнулся на это и понял, что ответы устарели. В этот день и в возрасте вы не должны реализовывать наборы, используя хеш-таблицы, за исключением случаев, когда вы делаете их в углах. Вы должны использовать sets.
Например:
> let set = new Set();
> set.add('red')
> set.has('red')
true
> set.delete('red')
true
> set.has('red')
false
Обратитесь к этому сообщению SO для получения дополнительных примеров и обсуждений: Способы создания набора в JavaScript?
Ответ 5
Возможный способ, особенно эффективный, если набор является неизменным, но все еще можно использовать с набором переменных:
var haystack = "monday tuesday wednesday thursday friday saturday sunday";
var needle = "Friday";
if (haystack.indexOf(needle.toLowerCase()) >= 0) alert("Found!");
Конечно, вам может понадобиться изменить разделитель в зависимости от строк, которые вы должны поставить там...
Более надежный вариант может включать в себя ограничения, гарантирующие, что ни "выходной день", ни "день" не могут сравниться положительно:
var haystack = "!monday!tuesday!wednesday!thursday!friday!saturday!sunday!";
var needle = "Friday";
if (haystack.indexOf('!' + needle.toLowerCase() + '!') >= 0) alert("Found!");
Может быть не нужно, если вход уверен (например, из базы данных и т.д.).
Я использовал это в Greasemonkey script, с преимуществом использования стога сена непосредственно из хранилища GM.
Ответ 6
Использование хеш-таблицы может быть более быстрой.
Какой бы вариант вы ни выбрали, его определенно стоит проверить свою эффективность по сравнению с альтернативами, которые вы считаете.
Ответ 7
Зависит от того, сколько значений есть.
Если существует несколько значений (менее 10-50), поиск по массиву может быть в порядке. Хэш-таблица может быть переполнена.
Если у вас много значений, хеш-таблица является наилучшим вариантом. Это требует меньше работы, чем сортировка значений и выполнение двоичного поиска.
Ответ 8
Я знаю, что это старый пост. Но чтобы определить, находится ли значение в наборе значений, мы можем манипулировать через массив indexOf()
, который ищет и обнаруживает настоящее значение
var myString="this is my large string set";
var myStr=myString.split(' ');
console.log('myStr contains "my" = '+ (myStr.indexOf('my')>=0));
console.log('myStr contains "your" = '+ (myStr.indexOf('your')>=0));
console.log('integer example : [1, 2, 5, 3] contains 5 = '+ ([1, 2, 5, 3].indexOf(5)>=0));
Ответ 9
Вы можете использовать ES6 включает.
var string = "The quick brown fox jumps over the lazy dog.",
substring = "lazy dog";
console.log(string.includes(substring));