Самый быстрый способ определить, находится ли значение в группе значений в 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));