2008-11-21 3 views
10

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

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

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

ответ

16

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

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

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

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

7

Вы можете использовать объект следующим образом:

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

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

+0

Это не работает. setOfValues ​​[x], где x не входит в набор, не будет оцениваться до неопределенного, это приведет к ошибке. Вы хотите: «x в setOfValues», чтобы проверить членство. – 2008-11-21 09:31:44

+0

Он будет оцениваться до неопределенного. Это не приведет к ошибке. Попробуйте. – Tomalak 2008-11-21 10:01:48

0

В зависимости от количества ценностей.

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

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

+0

Я думал, что все в JS было хеш-таблицей, arry просто 0 => firstentry, 1 => secondentry isnt it? – 2008-11-21 09:40:29

+0

@Trull: Я сомневаюсь. Массив отличается от Object и, вероятно, оптимизирован для производительности, хотя это будет зависеть от реализации. – PhiLho 2008-11-21 11:51:17

5

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

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

2

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

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.

3

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

Например:

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

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

Обратитесь к этому SO опубликовать другие примеры и обсуждения: Ways to create a Set in JavaScript?

0

Я знаю, что это старый пост. Но, чтобы обнаружить, если значение в наборе значений мы можем управлять через массив 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));

Смежные вопросы