Самый быстрый способ определить, находится ли значение в группе значений в Javascript

У меня есть группа строк в Javascript, и мне нужно написать функцию, которая определяет, принадлежит ли другая конкретная строка к этой группе или нет.

Как быстрее всего этого добиться? Можно ли поместить группу значений в массив, а затем написать функцию, которая просматривает массив?

Я думаю, что если я сохраню значения отсортированными и выполню двоичный поиск, он должен работать достаточно быстро. Или есть какой-нибудь другой умный способ сделать это, который может работать быстрее?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
16
0
16 340
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Использование хеш-таблицы может быть более быстрым вариантом.

Какой бы вариант вы ни выбрали, его определенно стоит протестировать на фоне рассмотренных вами альтернатив.

Вы можете использовать такой объект:

// 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, но вы можете легко провести некоторое тестирование производительности, чтобы сравнить его с другими вариантами выполнения.

Если значение может встречаться в вашем наборе более одного раза и для вас важно «как часто», вы также можете использовать увеличивающееся число вместо логического, которое я использовал в моем примере.

Это не работает. setOfValues ​​[x], где x отсутствует в наборе, не будет оцениваться как undefined, это вызовет ошибку. Вы хотите: «x in setOfValues» для проверки членства.

Simon Howard 21.11.2008 12:31

Будет оценено как undefined. Это не приведет к ошибке. Попробуйте сами.

Tomalak 21.11.2008 13:01

Зависит от того, сколько там ценностей.

Если есть несколько значений (от 10 до 50), поиск в массиве может быть нормальным. Хеш-таблица может быть излишней.

Если у вас много значений, хеш-таблица - лучший вариант. Это требует меньше работы, чем сортировка значений и выполнение двоичного поиска.

Я думал, что все в JS было хеш-таблицей, массив - это просто 0 => первое, 1 => второе, не так ли?

Andrew Bullock 21.11.2008 12:40

@Trull: Я в этом сомневаюсь. Array отличается от Object и, вероятно, оптимизирован для производительности, хотя это будет зависеть от реализации.

PhiLho 21.11.2008 14:51
Ответ принят как подходящий

Используйте хеш-таблицу и сделайте следующее:

// 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");
}

Использование оператора «in», вероятно, является более элегантным способом сделать это. +1

Tomalak 21.11.2008 13:30

Пытаясь танцевать вокруг AngularJS 'ng-if, я придумал такой синтаксис (сразу после прочтения этого ответа): ({value1: 1, value2: 1})[ 'value2' ] - автономный тест карты.

Kevin Teljeur 19.07.2017 18:57

Комментарий к упомянутым выше хеш-решениям. Фактически {} создает объект (также упомянутый выше), который может привести к некоторым побочным эффектам. Одна из них заключается в том, что ваш «хэш» уже предварительно заполнен методами объекта по умолчанию.

Итак, "toString" in setOfValues будет true (по крайней мере, в Firefox). Вы можете добавить еще один символ, например "." к вашим строкам, чтобы обойти эту проблему, или используйте объект Hash, предоставленный библиотекой «prototype».

Спасибо, что заметили это. Еще одна причина ненавидеть JavaScript.

Simon Howard 21.11.2008 15:05

Возможный способ, особенно эффективный, если набор неизменяем, но все еще можно использовать с набором переменных:

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, с преимуществом использования стога сена непосредственно из хранилища GM.

Наткнулся на это и понял, что ответы устарели. В наши дни вы не должны реализовывать наборы с использованием хэш-таблиц, за исключением крайних случаев. Вы должны использовать наборы.

Например:

> let set = new Set();
> set.add('red')

> set.has('red')
true
> set.delete('red')
true
> set.has('red')
false

Обратитесь к этому сообщению SO для получения дополнительных примеров и обсуждения: Способы создания набора в JavaScript?

Я знаю, что это старый пост. Но чтобы определить, находится ли значение в наборе значений, мы можем манипулировать с помощью массива indexOf(), который ищет и определяет настоящее значения.

var myString = "this is my large string set";
var myStr=myString.split(' ');
console.info('myStr contains "my" = '+ (myStr.indexOf('my')>=0));
console.info('myStr contains "your" = '+ (myStr.indexOf('your')>=0));

console.info('integer example : [1, 2, 5, 3] contains 5 = '+ ([1, 2, 5, 3].indexOf(5)>=0));

Можно использовать ES6 включает в себя.

var string = "The quick brown fox jumps over the lazy dog.",
  substring = "lazy dog";

console.info(string.includes(substring));

Другие вопросы по теме