В javascript, как вы ищите массив для подстроки соответствия - PullRequest
45 голосов
/ 29 декабря 2010

Мне нужно искать массив в JavaScript.Поиск будет соответствовать только части строки, так как для строки будут назначены дополнительные номера.Затем мне нужно будет вернуть успешно сопоставленный элемент массива с полной строкой.

т.е.

var windowArray = new Array ("item","thing","id-3-text","class");

Мне нужно найти элемент массива с "id-", и мне нужнотакже потяните остальную часть текста в элементе (т.е. "id-3-text").

Спасибо

Ответы [ 11 ]

36 голосов
/ 26 октября 2012

Если вы можете использовать Underscore.js в своем проекте, функция массива _. Filter () делает это несложно:

// find all strings in array containing 'thi'
var matches = _.filter(
    [ 'item 1', 'thing', 'id-3-text', 'class' ],
    function( s ) { return s.indexOf( 'thi' ) !== -1; }
);

Функция итератора может делать все, что вы хотите, до тех пор, пока она возвращает true для совпадений.Прекрасно работает.

Обновление 2017-12-03:
Это довольно устаревший ответ.Возможно, не самый эффективный вариант в большом пакете, но его можно записать более кратко лот и использовать собственные методы ES6 Array / String, такие как .filter() и .includes() сейчас:

// find all strings in array containing 'thi'
const items = ['item 1', 'thing', 'id-3-text', 'class'];
const matches = items.filter(s => s.includes('thi'));

Примечание: Нет поддержки <= IE11 для <code>String.prototype.includes() (Edge работает, учтите), но вы хорошо справляетесь с полифилом или просто возвращаетесь к indexOf().

13 голосов
/ 29 декабря 2010

В вашем конкретном случае вы можете сделать это просто со скучным старым счетчиком:

var index, value, result;
for (index = 0; index < windowArray.length; ++index) {
    value = windowArray[index];
    if (value.substring(0, 3) === "id-") {
        // You've found it, the full text is in `value`.
        // So you might grab it and break the loop, although
        // really what you do having found it depends on
        // what you need.
        result = value;
        break;
    }
}

// Use `result` here, it will be `undefined` if not found

Но если ваш массив разреженный , вы можете сделатьэто более эффективно с правильно разработанной петлей for..in:

var key, value, result;
for (key in windowArray) {
    if (windowArray.hasOwnProperty(key) && !isNaN(parseInt(key, 10))) {
        value = windowArray[key];
        if (value.substring(0, 3) === "id-") {
            // You've found it, the full text is in `value`.
            // So you might grab it and break the loop, although
            // really what you do having found it depends on
            // what you need.
            result = value;
            break;
        }
    }
}

// Use `result` here, it will be `undefined` if not found

Остерегайтесь наивных петель for..in, которые не имеют проверок hasOwnProperty и !isNaN(parseInt(key, 10)); вот почему .


Не по теме :

Другой способ написать

var windowArray = new Array ("item","thing","id-3-text","class");

- это

var windowArray = ["item","thing","id-3-text","class"];

... который менее типичен для вас и, возможно, (этот бит субъективен) немного легче читается.Два оператора имеют абсолютно одинаковый результат: новый массив с этим содержимым.

12 голосов
/ 01 сентября 2018

Люди здесь делают это слишком сложно. Просто сделайте следующее ...

myArray.findIndex(element => element.includes("substring"))

findIndex () - это метод ES6 более высокого порядка, который перебирает элементы массива и возвращает индекс первого элемента, который соответствует некоторым критериям (предоставляется в виде функции). В этом случае я использовал синтаксис ES6 для объявления функции более высокого порядка. element является параметром функции (это может быть любое имя), а жирная стрелка объявляет, что следует как анонимную функцию (которую не нужно заключать в фигурные скобки, если она не занимает более одной строки).

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

11 голосов
/ 18 января 2017

Просто найдите строку в старом стиле indexOf

arr.forEach(function(a){if (typeof(a) == 'string' && a.indexOf('curl')>-1) console.log(a);})
2 голосов
/ 20 апреля 2016

Простейший ванильный код Javascript для достижения этой цели -

var windowArray = ["item", "thing", "id-3-text", "class", "3-id-text"];
var textToFind = "id-";

//if you only want to match id- as prefix 
var matches = windowArray.filter(function(windowValue){
  if(windowValue) {
      return (windowValue.substring(0, textToFind.length) === textToFind);
  }
}); //["id-3-text"]

//if you want to match id- string exists at any position
var matches = windowArray.filter(function(windowValue){
  if(windowValue) {
      return windowValue.indexOf(textToFind) >= 0;
  }
}); //["id-3-text", "3-id-text"]
2 голосов
/ 27 апреля 2011

Интересное исследование некоторых альтернатив и их эффективности см. В последних публикациях Джона Ресига:

(Обсуждаемая здесь проблема немного отличается, так как элементы стога сена являются префиксами иглы, а не наоборот, но большинство решений легко адаптировать.)

1 голос
/ 30 марта 2019
let url = item.product_image_urls.filter(arr=>arr.match("homepage")!==null)

Массив фильтров со совпадением строк. Это легко и однострочный код.

1 голос
/ 26 апреля 2011

ref: Как в javascript найти в массиве совпадение подстроки

Приведенное здесь решение является общим в отличие от решения 4556343 # 4556343 , котороетребуется предыдущий анализ для определения строки, с которой join(), которая не является компонентом ни одной из строк массива.
Кроме того, в этом коде /!id-[^!]*/ более правильно, /![^!]*id-[^!]*/ для соответствия параметрам вопроса:

  1. "поиск в массиве ..." (строк или чисел, а не функций, массивов, объектов и т. Д.)
  2. "только для совпадения части строки"(совпадение может быть где угодно)
  3. "вернуть ... соответствующий ... элемент" (единственное, не ВСЕ, как в "... the ... elementS")
  4. "с полной строкой "(включая кавычки)

... Решения NetScape / FireFox (решение для JSON см. ниже):

javascript:         /* "one-liner" statement solution */
   alert(
      ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] .
         toSource() . match( new RegExp( 
            '[^\\\\]("([^"]|\\\\")*' + 'id-' + '([^"]|\\\\")*[^\\\\]")' ) ) [1]
   );

или

javascript:
   ID = 'id-' ;
   QS = '([^"]|\\\\")*' ;           /* only strings with escaped double quotes */
   RE = '[^\\\\]("' +QS+ ID +QS+ '[^\\\\]")' ;/* escaper of escaper of escaper */
   RE = new RegExp( RE ) ;
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   alert(RA.toSource().match(RE)[1]) ;

отображает "x'!x'\"id-2".
Возможно, проверка массива для поиска ВСЕХ совпадений будет «чище».

/* literally (? backslash star escape quotes it!) not true, it has this one v  */
javascript:                            /* purely functional - it has no ... =! */
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   function findInRA(ra,id){
      ra.unshift(void 0) ;                                     /* cheat the [" */
      return ra . toSource() . match( new RegExp(
             '[^\\\\]"' + '([^"]|\\\\")*' + id + '([^"]|\\\\")*' + '[^\\\\]"' ,
             'g' ) ) ;
   }
   alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;

отображает:

     "x'!x'\"id-2"

     "' \"id-1 \""

     "id-3-text"

Using, JSON.stringify():

javascript:                             /* needs prefix cleaning */
   RA = ["x'!x'\"id-2",'\' "id-1 "',   "item","thing","id-3-text","class" ] ;
   function findInRA(ra,id){
      return JSON.stringify( ra ) . match( new RegExp(
             '[^\\\\]"([^"]|\\\\")*' + id + '([^"]|\\\\")*[^\\\\]"' ,
             'g' ) ) ;
   }
   alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;

отображает:

    ["x'!x'\"id-2"

    ,"' \"id-1 \""

    ,"id-3-text"

морщины:

  • "Unescaped" глобальный RegExp равен /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/g с \ можно найти буквально.Чтобы ([^"]|\")* соответствовал строкам со всеми экранированными " как \", сам \ должен экранироваться как ([^"]|\\")*.Когда на это ссылаются как на строку, которая должна быть объединена с id-, каждый \ должен быть снова экранирован, следовательно ([^"]|\\\\")*!
  • Поиск ID, который имеет \, *, ", ..., также должны быть экранированы через .toSource() или JSON или ....
  • null результаты поиска должны возвращать '' (или "", как вПУСТАЯ строка, содержащая NO "!) Или [] (для всего поиска).
  • Если результаты поиска должны быть включены в программный код для дальнейшей обработки, тогда необходимо eval(), напримерeval('['+findInRA(RA,ID).join(',')+']').

--------------------------------------------------------------------------------

Отступление:
Рейды и побеги?Является ли этот код противоречивым?
Семиотика, синтаксис и семантика /* it has no ... =! */ решительно объясняют выход из конфликта цитируемых литералов.

Означает ли "no =":

  • "нет знака "=" "как в javascript:alert('\x3D') (Нет! Запустите его и посмотрите, что есть!),
  • " нет оператора javascript с оператором присваивания ",
  • " нет равных "как и в «ничем не идентичном в любом другом коде» (предыдущие решения кода демонстрируют наличие функциональных эквивалентов),
  • ...

Цитирование на другом уровне также можно выполнить с помощьюРежим URI протокола JavaScript ниже.(// комментарии заканчиваются на новой строке (иначе nl, ctrl-J, LineFeed, ASCII десятичный 10, восьмеричный 12, шестнадцатеричный A), который требует кавычек, поскольку вставка nl нажатием клавиши Return вызывает URI.)

javascript:/* a comment */  alert('visible')                                ;
javascript:// a comment ;   alert(  'not'  ) this is all comment             %0A;
javascript:// a comment %0A alert('visible but  %\0A  is wrong ')   // X     %0A
javascript:// a comment %0A alert('visible but %'+'0A is a pain to type')   ;

Примечание. Вырежьте и вставьте любую строку javascript: в качестве URI непосредственного режима (по крайней мере, максимум? В FireFox), чтобы сначала использовать javascript: в качестве схемы или протокола URI, а остальныекак этикетки JS.

0 голосов
/ 01 июля 2019

Я думаю, что это может вам помочь.У меня была похожая проблема.Если ваш массив выглядит следующим образом:

var array = ["page1","1973","Jimmy"]; 

Вы можете сделать простой цикл for для возврата экземпляра в массив, когда вы получите совпадение.пустая переменная, c для размещения нашего ответа.Затем мы перебираем массив, чтобы найти, где объект массива (например, «page1») соответствует нашему indexOf («page»).В данном случае это 0 (первый результат)

Рад расширяться, если вам нужна дополнительная поддержка.

0 голосов
/ 15 октября 2018

Вот ваш ожидаемый фрагмент, который дает вам массив всех совпадающих значений -

var windowArray = new Array ("item","thing","id-3-text","class");

var result = [];
windowArray.forEach(val => {
  if(val && val.includes('id-')) {
    result.push(val);
  }
});

console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...