Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Поиск в массиве, частичное совпадение (https://javascript.ru/forum/misc/36600-poisk-v-massive-chastichnoe-sovpadenie.html)

фонарик 21.03.2013 10:54

Поиск в массиве, частичное совпадение
 
Подскажите пожалуйста, как проверить есть ли элемент в массиве, используя в поиске часть его имени? Например, есть массив
var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"]
как проверить, есть ли в массиве элемент с частичным совпадением "яблок", и получить его номер в массиве?

dmitriymar 21.03.2013 11:07

Цитата:

Сообщение от фонарик
как проверить, есть ли в массиве элемент с частичным совпадением "яблок", и получить его номер в массиве?

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

рони 21.03.2013 11:08

фонарик,
а если элементов совпавших не 1 который выдавать?

фонарик 21.03.2013 11:14

Цитата:

Сообщение от рони (Сообщение 241819)
а если элементов совпавших не 1 который выдавать?

Совпадений больше 1 быть не может.

Пытался найти в гугле что-то на эту тему, но кроме обычного поиска по массиву, ничего не нашел. Регулярные выражения никак не даются в понимании, да и ранее подобной задачи никогда не встречал :-?

dmitriymar 21.03.2013 11:17

Цитата:

Сообщение от фонарик
Пытался найти в гугле что-то на эту тему, но кроме обычного поиска по массиву, ничего не нашел. Регулярные выражения никак не даются в понимании, да и ранее подобной задачи никогда не встречал

можно ещё так : http://ru.wikipedia.org/wiki/%D0%A0%...B9%D0%BD%D0%B0
а в рнр вообще есть функция для вычисления расстояния

rgl 21.03.2013 11:47

var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"];

function findPartial( a, s )
{
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf( s ) >= 0 )
      return i;
  return -1;
}

alert( findPartial( massiv, "яблок" ) );

фонарик 21.03.2013 11:54

Мсье rgl, спасибо вам за решение, надеюсь я все-таки смогу понять как оно работает. Да и регулярных выражений вроде как и нет :-?

dmitriymar 21.03.2013 13:07

var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"];
 
function findPartial( a, s )
{
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf( s ) >= 0 )
      return i;
  return -1;
}
 
alert( findPartial( massiv, "яблокo" ) );

Цитата:

Сообщение от фонарик
как проверить, есть ли в массиве элемент с частичным совпадением "яблок", и получить его номер в массиве?

rgl, Ну и ? Почему не выводит элемент с частичным совпадением?

rgl 21.03.2013 13:26

dmitriymar,
Из вопроса, а также из приведенного примера можно предположить, что под частичным совпадением понимается вхождение:
Цитата:

Сообщение от фонарик (Сообщение 241815)
Подскажите пожалуйста, как проверить есть ли элемент в массиве, используя в поиске часть его имени?

Если же понимать по-вашему, то надо сначала определиться сколько букв должно совпадать, чтобы это уже считалось частичным совпадением. Одной достаточно?

Я понял вопрос именно так (вхождение), единственное, в чем сомневался, так это искать везде или строго в начале. Если нужно строго вначале, то проверку >= 0 можно заменить на == 0

фонарик 21.03.2013 13:42

Частичное совпадение я обозначил весьма буквально - выражение в кавычках "яблок". Т.е нужно значение что в кавычках проверить нет ли точных совпадений в массиве, т.е елемента в котором есть все символы что в кавычках. Решение rgl то, что и хотелось в итоге получить :)

рони 21.03.2013 13:44

Вариант частичного совпадения ...
var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"];

function findPartial(a, s) {
    while (s) {
        var reg = new RegExp(s)
        for (var i = 0; i < a.length; i++)
            if (reg.test(a[i])) return i;
        s = s.slice(0, -1)

    }

    return -1;
}

alert(findPartial(massiv, "яблокo"));

dmitriymar 21.03.2013 13:45

Цитата:

Сообщение от rgl
dmitriymar,
Из вопроса, а также из приведенного примера можно предположить, что под частичным совпадением понимается вхождение:
Сообщение от фонарик Посмотреть сообщение
Подскажите пожалуйста, как проверить есть ли элемент в массиве, используя в поиске часть его имени?.....

Здесь больше к терминологии:
Полное вхождение
Частичное вхождение
Полное совпадение
Частичное совпадение - http://ru.wikipedia.org/wiki/%D0%A0%...B9%D0%BD%D0%B0 чем меньше расстояние тем выше частичное совпадение совпадение .

В вашем же случае , находится полное вхождение

var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"];
 
function findPartial(a, s) {
    while (s) {
        var reg = new RegExp(s)
        for (var i = 0; i < a.length; i++)
            if (reg.test(a[i])) return i;
        s = s.slice(1, -1)
 
    }
 
    return -1;
}
 
alert(findPartial(massiv, "яблосоус"))


тоже такой момент, и почемуто мне кажется что искомое вхождение всё таки больше похоже на 1 или 3 элемент поискового подмножества :)

rgl 21.03.2013 13:51

var massiv = ["яблочный пирог", "соус_острый", "яблоки_красные"];

function findPartial( a, s )
{
  var i;
  if( s.length > 3 ) {
    i = s.length - 3;
    var r = s.substr( i, 3 );
    while( --i >= 0 )
      r += "|" + s.substr( i, 3 );
    r = new RegExp( r );
    for( i = 0; i < a.length; ++i )
      if( r.test( a[i] ) )
        return i;
  } else {
    for( i = 0; i < a.length; ++i )
      if( a[i].indexOf( s ) >= 0 )
        return i;
  }
  return -1;
}

alert( findPartial( massiv, "острота" ) );

dmitriymar 21.03.2013 13:55

rgl,
http://www.snippy.ru/snippet/1634-an...na-javascript/
и естественно победитель с минимальным расстоянием , алгоритм используется активно и очень плотно

рони 21.03.2013 13:57

Цитата:

Сообщение от dmitriymar
3 элемент поискового подмножества

где вы увидели 3? 3элемент это как раз 2 индекс

dmitriymar 21.03.2013 13:59

рони,
да , запарился . в любом случае вариант на расстояниях решение гораздо правильнее

rgl 21.03.2013 14:00

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

рони 21.03.2013 14:04

Цитата:

Сообщение от rgl
если все равно все определяется тем, найдется ли более короткая.

в каком месте? поиск прекратится на самом большом совпадении

dmitriymar 21.03.2013 14:05

рони,
поправил тест . Сможете обосновать почему соус более релевантен чем яблоко?) яблоко ведь стоит в начале слова , и вполне логично , что более подходящий вариант связан с яблоком для стран с письменностью слева направо :)

рони 21.03.2013 14:07

Цитата:

Сообщение от rgl
Да и регэкспы без необходимости использовать зачем?

а как без них?

rgl 21.03.2013 14:08

Цитата:

Сообщение от dmitriymar (Сообщение 241850)
тоже такой момент, и почемуто мне кажется что искомое вхождение всё таки больше похоже на 1 или 3 элемент поискового подмножества :)

Кста, ТС уточнил, что ситуация, когда больше одного совпадения, невозможна, либо есть ровно одно совпадение, либо нет ни одного. А значит нет смысла сравнивать, какое совпадение больше похоже, а какое меньше. Более сложная задача требует более сложного решения, а вычисление степени совпадения (или как там его, расстояния) - задача не для JavaScript, средства языка не позволяют эффективно, т.е. на таком языке, как напр. С решение будет работать на порядок, если не на два, быстрее.

rgl 21.03.2013 14:10

Цитата:

Сообщение от рони (Сообщение 241866)
а как без них?

String.indexOf, String.lastIndexOf
Цитата:

Сообщение от рони (Сообщение 241861)
в каком месте? поиск прекратится на самом большом совпадении

Да, не обратил внимания сразу.

рони 21.03.2013 14:11

Цитата:

Сообщение от dmitriymar
поправил тест . Сможете обосновать почему соус более релевантен чем яблоко?) яблоко ведь стоит в начале слова , и вполне логично , что более подходящий вариант связан с яблоком для стран с письменностью слева направо

ничего не понял - где чего поправлено ... какой соус ... :blink:

фонарик 03.04.2013 20:16

Цитата:

Сообщение от rgl (Сообщение 241830)
var massiv = ["яблочный пирог","соус_острый_1","яблоки_красные","соус_острый_8"];

function findPartial( a, s )
{
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf( s ) >= 0 )
      return i;
  return -1;
}

alert( findPartial( massiv, "соус_острый" ) );

Я реализовал в своей задаче скрипт что выше, который написал мсье rgl. Он прекрасно работает для нужного мне поиска. Подскажите пожалуйста, как изменить данный скрипт так, чтобы в итоге в алерте увидеть все номера индексов найденных совпадений? Т.е в данном случае, необходимо получить индексы [1] и [3].

фонарик 03.04.2013 22:24

var massiv = ["яблочный пирог","соус_острый_1","яблоки_красные","соус_острый_8"];

function findPartial(a, s)
{
	var zz = []
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf(s) >= 0 )
	  zz.push(i)	  
	  return zz
  return -1;
}

alert( findPartial( massiv, "соус_острый" ) )
Вроде работает ))

rgl 04.04.2013 07:43

Цитата:

Сообщение от фонарик (Сообщение 244180)
var massiv = ["яблочный пирог","соус_острый_1","яблоки_красные","соус_острый_8"];

function findPartial(a, s)
{
	var zz = []
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf(s) >= 0 )
	  zz.push(i)	  
	  return zz
  return -1;
}

alert( findPartial( massiv, "соус_острый" ) )
Вроде работает ))

В какой-то из умных книжек (не помню в какой) написано что-то вроде "есть только одна вещь хуже отсутствия отступов - неправильные отступы"
var massiv = ["яблочный пирог","соус_острый_1","яблоки_красные","соус_острый_8"];

function findPartial(a, s)
{
  var zz = []
  for( var i = 0; i < a.length; ++i )
    if( a[i].indexOf(s) >= 0 )
	  zz.push(i)	  
  return zz // тут отсутп был неправильный, ибо выполняется всегда, а не внутри if
  // return -1; //а это вообще никогда не выполняется
}

alert( findPartial( massiv, "соус_острый" ) )


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