Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > Поиск значения в массиве


Автор: Gold Dragon 18.6.2012, 22:30
Что-то мозги кипят и ни как не могу сообразить как реализовать... попробую объяснить задачу..

есть массив со значениями следующей структуры
[string][-][int][-][int][-][string]
Пример
array('asd_qwe-1-0-qwe', 'qw_we-0-0-fr-ds', 'as_df-2-3-qwe')

Строки начинаются с буквы, но могут содержать и цифры и тире

Условия такие
1. Точное совпадение если нет в нуля
2. если есть ноль, то в значение может быть любым, по типу *

Автор: bars80080 18.6.2012, 23:24
Код

$search = 'some';
$arr = array('asd_qwe-1-0-qwe', 'qw_we-0-0-fr-ds', 'as_df-2-3-qwe');

$ret = array();

foreach($arr as $key => $v) {
    $pos = strpos($v, '0');
    if($pos !== false || $v == $search) { $ret[] = $key; }
}

Автор: Gold Dragon 19.6.2012, 07:14
немного не так объяснил наверное..
значения для поиска могут быть такие же как и то что ищут, вернее имеют тот же формат (состоят из 4 блока разделённых 'тире')

где ищем -> что ищем
'asd_qwe-1-0-qwe' -> 'asd_qwe-1-0-'
'qw_we-0-0-fr-ds' -> qw_we-0-0-fr-ds'
'as_df-2-3-qwe' -> 'as_df-2-0-qwe'


Думаю поиск должен быть регуляркой что-то типа
Код

#^([a-z0-9_-])+-(\d)+-(\d)+-([a-z0-9_-])+$#i

Автор: baldina 19.6.2012, 09:50
а вопрос то в чем?

Автор: Gold Dragon 19.6.2012, 10:09
есть таблица с данными, в т.ч. и с тем что искать.
Есть массив в котором есть данные которые уже указывал.

Необходимо листать данные полученные из таблицы и проверять одно поле на совпадение его в массиве

Идеальным вариантом было бы найти в массиве значение используя регулярку.. Но что-то такой простой функции типа in_array() нет (или я не знаю). Вот нужно придумать что-то своё и чтобы скорость не съедало

Автор: baldina 19.6.2012, 10:40
т.е. поиск в базе? ну так строишь регулярку, соответствующую всем шаблонам из массива используя http://dev.mysql.com/doc/refman/5.1/en/regexp.html

Автор: Gold Dragon 19.6.2012, 10:57
Цитата(baldina @  19.6.2012,  11:40 Найти цитируемый пост)
т.е. поиск в базе? 
нет же

1. есть массив
Код

$arr = array('asd_qwe-1-0-qwe', 'qw_we-0-0-fr-ds', 'as_df-2-3-qwe');


2. есть данные из базы.

3. Есть цикл
Код

foreach($rows as $row){}

в котором получаются данные, а так же формируется строка проверки в формате, в котором есть  в массиве

4. в цикле необходимо проверять данные из массива и сформированное значение.

5. Пример.
- в массиве есть значение "com-qwer-5-0-"
- сформировалось - "com-qwer-5-2-asd"

6. значения состоят из 4-х частей всегда, разделённое тире А-Б-В-Г
А - латиница, подчёркивание, тире, цифры
Б - только цифры
В - только цифры
Г - латиница, подчёркивание, тире, цифры, может быть пустым

7. Из примера. 
- В массиве 
  А = com-qwer
  Б = 5
  В = 0
  Г = 
- В сформированном 
  А = com-qwer
  Б = 5
  В = 2
  Г = asd

Если в массиве в Б или В ноль, то в сформированном значение игнорируется и при сравнении всегда ИСТИНА
Если в массиве в Г "", то в сформированном значение игнорируется и при сравнении всегда ИСТИНА

В примере значения "равны"

вот в этом примере ЛОЖ
- в массиве есть значение "com-qwer-5-2-"
- сформировалось - "com-qwer-5-0-asd"


Автор: baldina 19.6.2012, 13:17
Цитата(Gold Dragon @  19.6.2012,  10:57 Найти цитируемый пост)
- в массиве есть значение "com-qwer-5-0-"
- сформировалось - "com-qwer-5-2-asd"

по какому правилу сформировалось? (учитывая что $arr = array('asd_qwe-1-0-qwe', 'qw_we-0-0-fr-ds', 'as_df-2-3-qwe');)

Автор: Gold Dragon 19.6.2012, 13:25
да я уже объяснял же(!) ну куда подробнее?? не важно как они формируются, важно что они имеют вот такое значение
Цитата(Gold Dragon @  19.6.2012,  11:57 Найти цитируемый пост)
6. значения состоят из 4-х частей всегда, разделённое тире А-Б-В-Г
А - латиница, подчёркивание, тире, цифры
Б - только цифры
В - только цифры
Г - латиница, подчёркивание, тире, цифры, может быть пустым



Вот регулярка для расклада
Код

#^([a-z0-9_-]+)-(\d+)-(\d+)-([a-z0-9_-]*)$#i

Автор: Aliance 19.6.2012, 15:59
А что если разбить строку через explode и проверить 1 и 2 элементы на равенство нулю?

Автор: Gold Dragon 19.6.2012, 16:05
explode не получится, только регуляркой. Тире может быть и в первом и в последнем блоке, кроме разделителей

Добавлено через 57 секунд
а накидал один способ, у меня работает. Упростил как мог, но всё равно сложный получился.. сейчас выдерну из скрипта и выложу

Автор: Fortop 20.6.2012, 09:46
Цитата(Gold Dragon @  19.6.2012,  10:57 Найти цитируемый пост)
Если в массиве в Б или В ноль, то в сформированном значение игнорируется и при сравнении всегда ИСТИНА
Если в массиве в Г "", то в сформированном значение игнорируется и при сравнении всегда ИСТИНА

Это жесть smile

Зачем нужна строка, которая не строка, а структура?
Для чего себе создавать геморрой?

Автор: Gold Dragon 20.6.2012, 12:13
Fortop, если нет решения, то философия мне не нужна(!) без обид. Возьми любой серийный номер любой техники - это строка, которая и есть зашифрованная структура. 
Я имею набор таких "серийников" и у меня есть с чем их сравнивать. Так вот мне нужно или каждое значение из "справочника" приводить в структуру и сравнивать или структуру привести в строку и сравнить.. Второй вариант намного энергоёмкостнее  

Автор: Fortop 20.6.2012, 13:54
Цитата(Gold Dragon @  20.6.2012,  12:13 Найти цитируемый пост)
то философия мне не нужна

Это не философия.
Философия у вас в постановке задачи.
Сравнить жопу с пальцем наиболее эффективным способом - это не задача.

И решения нет по той причине, что нет проблемы. Какая конечная цель?
Найти серийник?
Или найти ряд серийников? Если ряд серийников, то по каким критериям? По маске? Какие правила формирования маски?

Вам задали вполне правильный вопрос
Цитата(baldina @  19.6.2012,  13:17 Найти цитируемый пост)
по какому правилу сформировалось?

Потому что это влияет на то, как решать задачу.

Добавлено через 5 минут и 8 секунд
Цитата(Gold Dragon @  20.6.2012,  12:13 Найти цитируемый пост)
 у меня есть с чем их сравнивать

Кстати, с чем все же сравниваются серийники?

Автор: Gold Dragon 20.6.2012, 14:09
Цитата(Fortop @  20.6.2012,  14:54 Найти цитируемый пост)
И решения нет по той причине, что нет проблемы. Какая конечная цель?
Найти серийник?
Или найти ряд серийников? Если ряд серийников, то по каким критериям? По маске? Какие правила формирования маски?

А прочитать то что я уже написал выше не судьба? Или там так очень кратко написано? особенно тут?
http://forum.vingrad.ru/index.php?showtopic=353382&view=findpost&p=2498560

Что за трёп? только слова и ничего больше, ни вопроса ни ответа, только эмоциональные жаргонизмы. Читай лучше мои пояснения. если не понятно задавай вопросы. Уже несколько раз сказал и про маску и про то какие данные, и с примерами, и с чем сравнивать

Добавлено через 9 минут и 39 секунд
вот рабочий код. Код выдернут из движка. Упростил как смог

сам метод
Код

    public static function MenuLinksSelect($arr, $selected){
        $html = '<select name="selections[]" class="inputbox" size="26" multiple="multiple">';
        foreach($arr as $key){
            $select = '';
            if($key->value !== -999){
                if($key->value === '')$key->value = '-0-0-';
                if($key->value == '0')$key->value = '0-0-0-';
                $tmp = preg_match("#^([a-z0-9_-]*)-(\d+)-(\d+)-([a-z0-9_-]*)$#i", $key->value, $arr_sel);
                foreach($selected as $sel){
                    if($tmp){
                        if($sel['option'] == ''){
                            $select = ' selected="selected"';
                        } else{
                            $error = 0;
                            if($arr_sel[1] == $sel['option'] or $sel['option'] == '') $error++;
                            if($arr_sel[2] == $sel['directory'] or $sel['directory'] == '0') $error++;
                            if($arr_sel[3] == $sel['category'] or  $sel['category'] == '0') $error++;
                            if($arr_sel[4] == $sel['task'] or $sel['task'] == '') $error++;
                            if($error == 4) $select = ' selected="selected"';
                        }
                    }
                }
            }
            $html .= '<option value="' . $key->value . '" ' . $select . '>' . $key->text . '</option>';
        }
        $html .= '</select>';
        return $html;
    }



Значение $arr
Код

array(26) {
  [0]=>
  object(stdClass)#149 (2) {
    ["value"]=>
    string(0) ""
    ["text"]=>
    string(6) "Все"
  }
  [1]=>
  object(stdClass)#150 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [2]=>
  object(stdClass)#151 (2) {
    ["value"]=>
    int(0)
    ["text"]=>
    string(22) "Отсутствуют"
  }
  [3]=>
  object(stdClass)#152 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [4]=>
  object(stdClass)#153 (2) {
    ["value"]=>
    string(18) "com_frontpage-0-0-"
    ["text"]=>
    string(31) "Главная страница"
  }
  [5]=>
  object(stdClass)#154 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [6]=>
  object(stdClass)#155 (2) {
    ["value"]=>
    string(13) "com_boss-6-6-"
    ["text"]=>
    string(46) "Файловый архив : Анектоды"
  }
  [7]=>
  object(stdClass)#156 (2) {
    ["value"]=>
    string(13) "com_boss-6-8-"
    ["text"]=>
    string(54) "Файловый архив : Фотозаставки"
  }
  [8]=>
  object(stdClass)#157 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [9]=>
  object(stdClass)#158 (2) {
    ["value"]=>
    string(13) "com_boss-5-1-"
    ["text"]=>
    string(33) "Основной : Новости"
  }
  [10]=>
  object(stdClass)#159 (2) {
    ["value"]=>
    string(13) "com_boss-5-2-"
    ["text"]=>
    string(31) "Основной : Статьи"
  }
  [11]=>
  object(stdClass)#160 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [12]=>
  object(stdClass)#161 (2) {
    ["value"]=>
    string(13) "com_boss-7-4-"
    ["text"]=>
    string(39) "Контакты : Мультгерои"
  }
  [13]=>
  object(stdClass)#162 (2) {
    ["value"]=>
    string(13) "com_boss-7-5-"
    ["text"]=>
    string(55) "Контакты :   - Иностранные"
  }
  [14]=>
  object(stdClass)#163 (2) {
    ["value"]=>
    string(13) "com_boss-7-6-"
    ["text"]=>
    string(53) "Контакты :   - Российские"
  }
  [15]=>
  object(stdClass)#164 (2) {
    ["value"]=>
    string(13) "com_boss-7-7-"
    ["text"]=>
    string(39) "Контакты : Президенты"
  }
  [16]=>
  object(stdClass)#165 (2) {
    ["value"]=>
    string(13) "com_boss-7-8-"
    ["text"]=>
    string(31) "Контакты : Учёные"
  }
  [17]=>
  object(stdClass)#166 (2) {
    ["value"]=>
    int(-999)
    ["text"]=>
    string(12) "------------"
  }
  [18]=>
  object(stdClass)#167 (2) {
    ["value"]=>
    string(16) "com_banners-0-0-"
    ["text"]=>
    string(14) "Баннеры"
  }
  [19]=>
  object(stdClass)#168 (2) {
    ["value"]=>
    string(13) "com_poll-0-0-"
    ["text"]=>
    string(12) "Опросы"
  }
  [20]=>
  object(stdClass)#169 (2) {
    ["value"]=>
    string(14) "com_login-0-0-"
    ["text"]=>
    string(22) "Авторизация"
  }
  [21]=>
  object(stdClass)#170 (2) {
    ["value"]=>
    string(15) "com_search-0-0-"
    ["text"]=>
    string(10) "Поиск"
  }
  [22]=>
  object(stdClass)#171 (2) {
    ["value"]=>
    string(18) "com_syndicate-0-0-"
    ["text"]=>
    string(18) "RSS экспорт"
  }
  [23]=>
  object(stdClass)#172 (2) {
    ["value"]=>
    string(17) "com_massmail-0-0-"
    ["text"]=>
    string(27) "Рассылка почты"
  }
  [24]=>
  object(stdClass)#173 (2) {
    ["value"]=>
    string(13) "com_xmap-0-0-"
    ["text"]=>
    string(21) "Карта сайта"
  }
  [25]=>
  object(stdClass)#174 (2) {
    ["value"]=>
    string(14) "com_elrte-0-0-"
    ["text"]=>
    string(16) "elFinder + elRTE"
  }
}

Значение $selected
Код

array(2) {
  [0]=>
  array(4) {
    ["option"]=>
    string(13) "com_frontpage"
    ["directory"]=>
    string(1) "0"
    ["category"]=>
    string(1) "0"
    ["task"]=>
    string(0) ""
  }
  [1]=>
  array(4) {
    ["option"]=>
    string(8) "com_boss"
    ["directory"]=>
    string(1) "5"
    ["category"]=>
    string(1) "0"
    ["task"]=>
    string(0) ""
  }
}


Автор: Fortop 20.6.2012, 14:35
Цитата(Gold Dragon @  20.6.2012,  14:09 Найти цитируемый пост)
А прочитать то что я уже написал выше не судьба? Или там так очень кратко написано? особенно тут?

Там каша.

По сути вашего описания в массиве находятся маски.
И вы хотите найти подходящие под них значения в БД.

Вам вполне конкретно ответили
Цитата(baldina @  19.6.2012,  10:40 Найти цитируемый пост)
т.е. поиск в базе? ну так строишь регулярку, соответствующую всем шаблонам из массива используя mysql regexp 

А это ваш ответ
Цитата(Gold Dragon @  19.6.2012,  10:57 Найти цитируемый пост)
нет же


Что-то еще нужно прочитать?
Или вам нужно таки понять, что же вы делаете?

Если в массиве не маски, то что?
Плюс в этом случае остается актуальным вопрос
Цитата(baldina @  19.6.2012,  13:17 Найти цитируемый пост)
по какому правилу сформировалось?



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

Добавлено через 1 минуту и 25 секунд
Цитата(Gold Dragon @  20.6.2012,  14:09 Найти цитируемый пост)
Значение $selected

Ну таки структура, которую вы зачем-то приводите к строке.
Зачем?

Автор: Gold Dragon 20.6.2012, 14:48
Fortop, всё понятно, читать и понимать просто лень... бывает.. тогда так

То что ты называешь масками тоже являются значениями, например, "com_boss-6-6-" означает
1. com_boss - применимо для компонента com_boss и это значение должно содержаться в ($_GET или $_POST) в option
2. 6 - распространяется если компонент com_boss и категория с ID=6
3. 6 - распространяется если компонент com_boss, категория с ID=6 и каталог ID=6
4. '' - означает что привязка к разделам каталога не осуществляется

Эти значения являются своеобразными идентификаторами URL, так же используются в VALUE в <FORM>, ну и ещё кое где

Этот список более-менее постоянный и достаточно большой

Далее с чем сравнивать или что сравнивать. В данном случае это как настроен определённый отображаемый объект на сайте. Например, если у нас в третьей части стоит ноль, то это означает что нам доступны данные не только из каталога ID=6, а из всей категории. Если там что-то иное чем ноль, то тогда уже реагируем на значение

ps
хотя я уже не знаю как объяснить.. смотри код, может так поймёшь. Код рабочий и мои требования выполняет

Добавлено через 45 секунд
Цитата(Fortop @  20.6.2012,  15:35 Найти цитируемый пост)
Ну таки структура, которую вы зачем-то приводите к строке.
Зачем? 
не понял предложения

Автор: Fortop 20.6.2012, 14:56
Acl знакомо?

Можно посмотреть Zend_Acl
phpgacl

Вот туда и копать.


А сравнивать в этом(вашем) случае лучше не строки, а таки структуры по уровням иерархий.

Автор: Gold Dragon 20.6.2012, 15:09
вот у нас есть функции которые ищут в строке строку по регулярным правилам. А мне нужно чтобы точно так же, но только поиск в массиве... Вот собственно к чему вся эта тема

Цитата(Fortop @  20.6.2012,  15:56 Найти цитируемый пост)
Можно посмотреть Zend_Acl
phpgacl
а это вообще зачем?

Автор: Fortop 20.6.2012, 16:07
Цитата(Gold Dragon @  20.6.2012,  15:09 Найти цитируемый пост)
 А мне нужно чтобы точно так же, но только поиск в массиве...

Код

array_walk($array, function($item) use (&matches) {
// тут ищем.
});



Цитата(Gold Dragon @  20.6.2012,  15:09 Найти цитируемый пост)
а это вообще зачем?

http://en.wikipedia.org/wiki/Access_control_list

А ноги растут отсюда.
Цитата(Gold Dragon @  20.6.2012,  14:48 Найти цитируемый пост)
Например, если у нас в третьей части стоит ноль, то это означает что нам доступны данные не только из каталога ID=6, а из всей категории. Если там что-то иное чем ноль, то тогда уже реагируем на значение


Т.е. вам нужно определить доступен ли элемент иерархии.

Автор: baldina 20.6.2012, 16:10
Цитата(Gold Dragon @  20.6.2012,  14:48 Найти цитируемый пост)
Fortop, всё понятно, читать и понимать просто лень... бывает.. тогда так

я читал внимательно и непониманием не страдаю. однако прекратил анализ Вашей задачи лишь потому что Вы её толком не сформулировали, а догадываться на основе ваших обмолвок и многакода желания и времени нет.
Цитата(Gold Dragon @  20.6.2012,  15:09 Найти цитируемый пост)
 А мне нужно чтобы точно так же, но только поиск в массиве...

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

Автор: Gold Dragon 20.6.2012, 20:39
Fortop, к сожалению я лучше знаю русский чем английский.

baldina, что не понятно в этом ответе?
 http://forum.vingrad.ru/index.php?showtopic=353382&view=findpost&p=2498560


Цитата(baldina @  20.6.2012,  17:10 Найти цитируемый пост)
если вопрос только в этом (хотя полагаю такая формулировка не полна или даже неверна), то постройте одно регулярное выражение из всех элементов массива, части которого разделены предикатом "|" (или). это соответствует Вашим словам, но слишком просто что бы быть правдой
именно да. это просто на словах. реализация получилась такая, которую я показал. Задачи изначально стояла именно искать в массиве строку из другого массива при помощи регулярки... Конечно цель основная другая, но мне нужно именно этот кусок.

Тему можно закрыть. Реализацию я сделал, может не оптимальную, но работает. Со временем поправлю. Просто очень много времени потратил на перебранки, за что прошу прощение если кого обидел ненароком ;) Ответ получился простой: строку в строке регуляркой искать можно, в массиве нет, для поиска в массиве нужно изобретать что-то иное..

Автор: Evghenusi 20.6.2012, 21:45
почитал, офигел.

может?
Код

#^([\w-]+)-(\d+)-([^0])-([\w-]+)$#
или
#^([\w-]+)-(\d+)-(0)-([\w-]+)$#

хотя наверно мимо, но всё равно оставлю сообщение, авось...

Автор: Gold Dragon 20.6.2012, 22:05
Evghenusi, вопрос то не в регулярке... Нужно найти значение из одного массива в другом при помощи регулярки

Автор: skyboy 20.6.2012, 22:43
Цитата(Gold Dragon @  20.6.2012,  19:39 Найти цитируемый пост)
 строку в строке регуляркой искать можно, в массиве нет, для поиска в массиве нужно изобретать что-то иное..

array_filter
сначала — БД и массив. потом — два массива. потом — два массива и регулярки.
как только казалось, что начинаю понимать — попадалось новое сообщение, додказывающее обратное.
общий совет: хочешь скорости, уходи от регулярок. раз у тебя строка имеет определенную структуру, то парсь её сразу же и работай уже со структурой, а не с трехэтажными регулярками.

Автор: Gold Dragon 20.6.2012, 23:17
array_filter - видимо это то что я искал smile нужно ещё прикинуть всё.. Но вот от регулярки видимо уйти не получится, данные специфические.. Или придётся вводить в место одной переменной ещё три... хотя как потом их использовать в HTML формах ещё подумать нужно

Добавлено через 2 минуты и 55 секунд
Цитата(skyboy @  20.6.2012,  23:43 Найти цитируемый пост)
как только казалось, что начинаю понимать — попадалось новое сообщение, додказывающее обратное.
да вот пробою пояснить подробно, больше запутываю. в конечно итоге сравниваются те данные которые я привёл в листинге, вывел специально с типами

Автор: Fortop 21.6.2012, 11:26
Цитата(Gold Dragon @  20.6.2012,  20:39 Найти цитируемый пост)
Fortop, к сожалению я лучше знаю русский чем английский.

Есть на русском http://ru.wikipedia.org/wiki/ACL

Суть в том, как организовать наследование прав доступа и определить доступен ли данный элемент для действий.
Там же попутно решается тот вопрос, который вы разбирали в этой теме.

Автор: Gold Dragon 21.6.2012, 11:56
Fortop, это слишком сложно. Задача намного проще.. и я вроде её уже порешал.. сейчас ещё попробую с array_filter поиздеваться...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)