Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Поиск по массиву (https://javascript.ru/forum/misc/37279-poisk-po-massivu.html)

1lider 13.04.2013 21:16

Поиск по массиву
 
Добрый вечер.

Имеются у нас такие данные:
var str = "A=1111&B=2222&C=3333"; // исходная строка
var str_array = str.split("&"); // разбираем строку и помещаем в массив. Всего в массиве, три элемента
var mask_array = ["A=", "B=", "C="]; // маска


Здесь, мы разобрали строку и поместили в массив. Всего в массиве получилось 3 элемента. Так же мы обьявили массив с маской. Каждый элемент маски, по отдельности, должен использваться в поиске по массиву str_array. Вопрос. Как с помощью цикла, найти и удалить элементы в массиве str_array, используя маску? То есть, сначала в str_array ищем "A=", затем "В=", и так далее. У меня есть один вариант, простой, но он слишком громоздкий.

Поможете разобраться?

Aves 13.04.2013 21:40

Если я правильно понял, то из str_array нужно удалить элементы, соответствующие маске? Тогда так:
res = str_array.filter(function(e){return !mask_array.some(function(m){return new RegExp(m).test(e)})})

Останутся только элементы, не соответствующие маске.

1lider 13.04.2013 21:59

Цитата:

Если я правильно понял, то из str_array нужно удалить элементы, соответствующие маске?
Да, именно так. Кстати, ваш вариант у меня выдает ошибку: Объект не поддерживает это свойство или метод. Все правильно в коде?

Ervin 13.04.2013 22:06

IE 8 Не поддерживает метов Array.filter и Array.some.

1lider 13.04.2013 22:07

Цитата:

IE 8 Не поддерживает метов Array.filter и Array.some.
Ну вот, опять тупик.

Ervin 13.04.2013 22:19

Совсем нет.
var str = "A=1111&B=2222&C=3333",
     regExp = /(A|B|C)=(\d){1,}(&)?/g
     clearedStr = str.replace(regExp, "");


Если нет нужды работать с массивами.

1lider 13.04.2013 23:22

Вариант отличный. Но к сожалению, он работает со строкой, а не с массивом. Вот в php хорошо, там например есть встроенная функция in_array();, а в javascript я так понимаю, с этим дело несколько напряжно. У меня есть вот такой вариант решения моей проблемы. Но как я говорил, он громоздкий, но без маски:

var str = "A=1111&B=2222&C=3333";
var str_array = str.split("&");
var size = str_array.length;
for(var i = 0; i < size; i++) {
   if(str_array.indexOf("A=") != -1) {
      str_array.splice(i, 1);
      i--;
      size--;
   }
   if(str_array.indexOf("B=") != -1) {
      str_array.splice(i, 1);
      i--;
      size--;
   }
   if(str_array.indexOf("C=") != -1) {
      str_array.splice(i, 1);
      i--;
      size--;
   }
}

dastingo 13.04.2013 23:33

inArray можно утянуть из jQuery по-быстрому.
1lider,
str_array.indexOf("A=") когда там 'A=1111' -1 же всегда

Ervin 13.04.2013 23:35

var str = "A=1111&B=2222&C=3333&D=13123",
     strArray = str.split("&"),
     toRemove = ["A=", "B=", "C="];

for(var i = 0; i < strArray.length; i++) {
  for(var n = 0, lengN = toRemove.length; n < lengN; n++) {
      if(~strArray[i].indexOf(toRemove[n])) {
           strArray.splice(i, 1);
           i--;
           break;
      }
  }
}

9xakep 13.04.2013 23:36

лолчто

var str = "A=1111&B=2222&C=3333"; // исходная строка
var str_array = str.split("&"); // разбираем строку и помещаем в массив. Всего в массиве, три элемента
var mask_array = ["A=", "B=", "C="]; // маска

for (i=0;i<str_array.length;i++) {
   str_array[i] = str_array[i].replace(mask_array[i], "");
}

alert(str_array)

1lider 13.04.2013 23:50

Ervin. Благодарю, ваш вариант, как раз то что нужно. 9xakep. Вариант отличнейший, но задачка немножко другая. Задача в том, чтобы удалить элемент из массива, а не часть строки в каждом элементе.:)

9xakep 14.04.2013 00:33

1lider,
нужно удалить элемент таам где есть содержимое маски?

dastingo 14.04.2013 00:48

я бы убрал
i--;
break;

1lider 14.04.2013 00:59

Цитата:

нужно удалить элемент там где есть содержимое маски?
Да, именно так.

1lider 14.04.2013 01:01

Цитата:

я бы убралi--;
break;
Эти строки, удалять там никак нельзя.

dastingo 14.04.2013 01:08

ну я попробовал вариант, который предложил Ervin без i-- и break, с разноперемешанными строками
A=1111&B=2222&C=3333&D=13123
D=13123&A=1111&B=2222&C=3333
A=1111&B=2222D=13123&&C=3333
ок работает, минус 2 строчки.

1lider 14.04.2013 01:11

dastingo. Да, вы правы можно и убрать. Я тоже попробовал. Странно, разве элементы массива не сдивагаются на один индекс назад...

Цитата:

минус 2 строчки.
Оп, стоп. Почему 2 строчки? В его варианте, должны минусоваться всего три строчки.:)

dastingo 14.04.2013 01:33

На 2 строчки меньше написанного)
Там задумано, чтоб всё сдвигалось как надо.

1lider 14.04.2013 01:46

["A=1111", "B=2222", "C=3333", "D=13123"] - 4 элемента
["A=", "B=", "C="] - 3 элемента

Нее, там эти строки, все же нужны. Так как элементы массива, при удалении, сдвигаются назад. И записью i--; мы как раз учитываем это.:)

Ervin 14.04.2013 01:49

Убрав break, можно столкнуться с ситуацией когда strArray[i] undefined и будет TypeError. Поэтому я рекомендую оставить как есть.

dastingo 14.04.2013 04:06

Ervin,
возможно)
на всяких "D=13123&D=13123&A=1111&D=13123&D=13123&B=2222&D=1 3123&C=3333&D=13123&D=13123"
ничего подводного не возникало.

Ervin 14.04.2013 13:49

var str = "D=13123&D=13123&A=1111&D=13123&D=13123&B=2222&D=1 3123&C=3333&D=13123&D=13123",
     strArray = str.split("&"),
     toRemove = ["D=", "B=", "C="];

for(var i = 0; i < strArray.length; i++) {
  for(var n = 0, lengN = toRemove.length; n < lengN; n++) {
      if(~strArray[i].indexOf(toRemove[n])) {
           strArray.splice(i, 1);
           i--;
      }
  }
}


В первый же проверки удаляется первый элемент массива, после чего происходит проверка следующего элемента из массива toRemove, где strArray[-1] === undefined -> TypeError.

Aetae 14.04.2013 14:26

Нормальные люди перебирают с конца и не изобретают велосипед.

1lider 14.04.2013 14:46

Цитата:

Нормальные люди перебирают с конца и не изобретают велосипед.
Aetae. Чем, в данном варианте, перебор с конца, отличается от перебора с начала? Просвятите пожалуйста. В данном варианте, я разницы не наблюдаю.:)

Ervin 14.04.2013 15:43

Цитата:

Сообщение от Aetae (Сообщение 246141)
Нормальные люди перебирают с конца и не изобретают велосипед.

Тоесть единая истина это перебор с конца ? )) Вздор, это лично ваши предпочтения.

Aetae 14.04.2013 22:12

Цитата:

Сообщение от 1lider (Сообщение 246142)
Aetae. Чем, в данном варианте, перебор с конца, отличается от перебора с начала? Просвятите пожалуйста. В данном варианте, я разницы не наблюдаю.:)

var str = "D=13123&D=13123&A=1111&D=13123&D=13123&B=2222&D=1 3123&C=3333&D=13123&D=13123",
    strArray = str.split("&"),
    i = strArray.length,
    toRemove = ["D=", "B=", "C="];

while(i--) {
    for(var l = toRemove.length; l--;) {
        if(~strArray[i].indexOf(toRemove[l])){
            strArray.splice(i, 1);
            break;
        }
    }
}
alert(strArray.join('\n'))

Цитата:

Сообщение от Ervin (Сообщение 246146)
Тоесть единая истина это перебор с конца ? )) Вздор, это лично ваши предпочтения.

По большей части да - мои предпочтения. Но не на пустом месте:
1. Запись лаконичнее.
2. Перебор часто используется совместно c удалением\изменением элементов как массивов так и dom и при обратном переборе вообще не надо задумываться об изменениях длины и прочего.(пример прямо сверху).
3. Тесты некогда показали, что обратный перебор dom немного быстрее. Как сейчас в принципе не важно уже.)
4. ...
5. Profit!

dastingo 14.04.2013 22:40

Ervin,
ну понятно - просто говорили о разном. я в своих экспериментах отбрасывал не только break, но и i--.


Часовой пояс GMT +3, время: 03:29.