|
|
|
| Здравствуйте, джентельмены! Помогите даме, пожалуйста, с такой задачей:
У меня есть файл с данными. Оттуда я их читаю в массив, а потом делю этот массив на подмассивы.
Еще есть переменные, в которые передаются или слова, или цифры, или вообще ничего, они в том же порядке, что и подмассивы.
Теперь сказали найти в подмассивах совпадения.
$peremen = array($a,$b,$c,$d,$e,$f,$j);
$result = count($peremen);
$file = "massiv.txt";
if (is_file($file)):
{
$fp = fopen($file, "r") ;
$file_array = file("massiv.txt"); // Считывание файла в массив $file_array-считывается
fclose($fp);
}
$podmassiv = array_chunk($file_array,$result);//делит на подмассив
foreach ($podmassiv as $key => $value){
foreach ($value as $pers => $value)
if (preg_match.........................................
|
А как делать дальше?
Заранее благодарю. | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 15:15)
| | Функции пересечения массивов смотрите.
PS. Правда, если значания первого массива, имеют такие же значения как и части массивов из файла. Иначе поможет strpos.
Вы бы лучше примеры значений массивов привели, вместо переменных, чтобы более понятно было чего сравнивать, сдается, что вполне можно обойтись без рег. выражений. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 15:28)
| | массив:
array [] = (васильчиков, вася, муж, 152, 29);
array [1]= (любина, люба, жен, 180, 80);
из формы поиска получаем 5 переменных.
например,
$a = "любина"
$b = "люба"
$c = "жен"
$d = "180"
$e = "80"
или, к примеру, несколько переменных могут вернуться пустыми, если кто-то решит искать "люба" и "80".
В первом случае поиск должен найти array [1]= (любина, люба, жен, 180, 80) и вывести, а во втором найти и вывести всех люб, которым 80. (с фамилией и всеми атрибутами) | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 16:19)
| | А вы не задумывались хранить такие данные не в файле, а в базе? И искать будет легче, и не потребуется таких примудростей для поиска. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 16:43)
| | там условия такие были | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 16:51)
| | Странно, такие данные так и просятся в таблицу.
Ну ладно, так значит так. Тогда повторяю - вам нужны функции персечения массивов. Если при сравнении будет возвращен массив совпадающих данных, то массив в котором происходит сравнение содержит искомые данные. Разберетесь?
PS. Вот этот момент:
$result = count($peremen);
.....
$podmassiv = array_chunk($file_array,$result);
не понятен. Зачем разбивать на такие куски массив из файла? | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 16:58)
| | Потому что из пяти форм данные первоначально записываются в файл по одному элементу с концом строки.
И когда я из файла массив достаю так:
$fp = fopen($file, "r") ;
$file_array = file("massiv.txt");
получаются, что все данные идут подряд:
[0]=>васильчиков
[1]=.>вася
[2]]=>муж
[3]=>150
и тд
А мне же нужно искать пять переменных, в том же порядке, что они вносились в файл.
Поэтому я просто разбиваю массив на подмассивы по 5 элементов
array[0]
васильчиков
вася
муж
150
29
array[1]
любина
люба
жен
180
80
логически видится, что предматч как-то должен быть в цикле, но до конца не соображается.
Апдейт: смотрю функции пересечения сейчас, но что-то не пойму.
Если у меня несколько переменных будут пустыми, каким образом применять функцию?
В этом случае, наверное, поиск будет работать некорректно? | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 17:13)
| | Если даже и хранить это в файле, то лучше в виде сериализованного массива.
Ну допустим пусть будет так, как есть, но для работы нужно будет полученные строки из файла преобразовать в массив, то есть получить многомерный массив. Вот именно такой и надо держать в файле. Разбивать что-то.... этого я так и не понял. Не понятен момент от каких пяти форм данные? У вас что каждый запрос (фамилие, имя, пол...), это разные формы? Если так, то это глупо.
Допустим, что у вас файл хранит данные о неких товарищах, особях муж/женск. пола, а в форме вы посылаете запрос на поиск среди этих товарищей нужного. К примеру, файл 'name.txt' содержит следующие данные (учитываю написание первых символов, и об этом надо помнить, для данного примера):
любина, люба, жен, 180, 80
колина, кира, жен, 160, 70
васильчиков, вася, муж, 152, 29
степанова, люба, жен, 160, 70
|
Далее делаем так:
<?
if($_POST) { //если пришел запрос на поиск
//получаем список
$a = file('name.txt');
//преобразуем его в многомерный массив
$m = array(); //многомерный массив $m будет содержать список наших особей
foreach($a as $v) array_push($m, array_map('trim', explode(',',$v)));
//вот что получаем - вот так данные лучше держать в файле
echo '<pre>'; //это для контроля, можно удалить
print_r($m); //это для контроля, можно удалить
//удаляем пробелы в элементах массива запроса на поиск
$_POST = array_map('trim', $_POST);
//поиск
foreach($m as $key=>$val) {
//если пересечение возвращает один или несколько запрашиваемых данных
//то выводим эти данные
if(array_intersect($val, $_POST)) echo implode(' ', array_map('ucfirst', $val)) . '<br>';
//если нужен поиск именно по совпадению всех данных,
//а не по любым из них, то достаточно поставить такое уловие,
//переписав строку сравнения массивов так:
if(array_intersect($val, $_POST) && count($_POST)==count(array_intersect($val, $_POST)))
echo implode(' ', array_map('ucfirst', $val)) . '<br>';
//заметьте, что здесь первые символы элементов переведены в верхний регистр
}
}
?>
<form action="" method="post">
Фамилия: <input type="text" name="fm"><br>
Имя: <input type="text" name="nm"><br>
Пол: <input type="text" name="sx"><br>
Рост: <input type="text" name="wh"><br>
Возраст: <input type="text" name="ag"><br>
<input type="submit" value="Искать">
</form>
|
Это пример, но суть, о которой я говорил выше, в этом - массив (именно массив, а не строка разделенная запятыми) из списка, сравнивается с массивом полученным из формы.
PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 18:06)
| | >Если даже и хранить это в файле, то лучше в виде сериализованного массива.
>Ну допустим пусть будет так, как есть, но для работы нужно будет полученные строки из файла преобразовать в массив, то есть получить многомерный массив. Вот именно такой и надо держать в файле.
>Разбивать что-то.... этого я так и не понял. Не понятен момент от каких пяти форм данные? У вас что каждый запрос (фамилие, имя, пол...), это разные формы? Если так, то это глупо.
Конечно, многое еще глупо, я только разбираюсь для себя, как это все работает. Со временем разберусь, от простого к сложному.
Форма одна, но массив из нее я раздробила на 5 переменных, во-первых, мне так легче сейчас понимать, что происходит,
а во-вторых, мне почему-то показалось, что так поиск будет работать корректней.
Наверняка есть лучший способ, но пусть хотя бы так заработает для начала.
>Это пример, но суть, о которой я говорил выше, в этом - массив (именно массив, а не строка разделенная запятыми) из списка, сравнивается с массивом полученным из формы.
Да, вот тут меня что-то смущает.
Если он возвращает все пересечения, то он мне вернет и то, что мне не нужно.
Например, имя Василий, фамилие Люба.
А искалось имя "Люба". И тогда и с Василием получается пересечение. Или я тут не права, насколько я успела пробежаться по мануалам, мне показалось именно так?
Потом, почему я еще склоняюсь к preg_match. Если строка пришла пустая, то ей проверкой можно присвоить " /* " - или не помню щас, как там было, чтобы этот порядковый элемент не сравнивать.
>PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне.
Щас вот вроде получился упрощенный пример:
<?php
$a=array("gun", "goos", "grey");
$array1[0] = array ( "green", "yellow", "red");
$array1[1] = array ( "gun", "goos", "grey");
$array1[2] = array ( "gu", "gos", "gey");
foreach($array1 as $key => $value){
foreach($value as $per) echo"<li> $per";
echo"<br><br>";
foreach($a as $val)
if (preg_match("/^($val)$/i", $per)) {
$print = (array_values($array1[$key]));
}
}
echo"<br><br>";
foreach($print as $value) echo"<li> $value";
?>
|
Не, не получился( | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 19:27)
| | Ну а для рег. выражению вы ведь тоже будете задавать условие "и Вася и Люба", причем рег выражение совсем не понимает, что Люба, это фамилие, а не имя.
Потому я и говорил, что такие вещт нужно деражать не в файле, а в таблице и скать по полям ее. Собственно функций персечений массива не одна, и есть среди них те, которые учиьывают и ключи массива. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 20:26)
| | >Ну а для рег. выражению вы ведь тоже будете задавать условие "и Вася и Люба", причем рег выражение совсем не понимает, что Люба, это фамилие, а не имя.
не обязательно, условие может быть просто "Люба"
>Потому я и говорил, что такие вещт нужно деражать не в файле, а в таблице и скать по полям ее. Собственно функций персечений массива не одна, и есть среди них те, которые учиьывают и ключи массива.
Буду читать сейчас внимательнее про функции. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 18:06)
| |
foreach($a as $v) array_push($m, array_map('trim', explode(',',$v)));
|
А что делает вот эта штука? Что-то не могу понять
>PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне.
форма такая:
<form action="form_process_searching.php" method="post">
<p>Регион:
<input type="text" name="reg">
Метро/Район:
<input type="text" name="mtr_ryn">
улица:
<input type="text" name="strt">
комнат:
<input type="text" name="kol_kom">
</p>
<p>№ дома:
<input type="text" name="nomer">
Общаяя площадь:
<input type="text" name="obsh_pl">
цена:
<input type="text" name="cena">
<input type="submit" name="submit" value="найти">
</p>
</form>
|
код такой:
<?php
$region = $_POST['reg'];
$metro_rayon = $_POST['mtr_ryn'];
$street = $_POST['strt'];
$komnat = $_POST['kol_kom'];
$nomer_doma = $_POST['nomer'];
$obshaya_pl = $_POST['obsh_pl'];
$cena = $_POST['cena'];
$peremen = array($region,$metro_rayon,$street,$komnat,$nomer_doma,$obshaya_pl,$cena);
$result = count($peremen);
echo $result."<br>";
$file = "massiv.txt";
if (is_file($file)):
{
$fp = fopen($file, "r") ;
$file_array = file("massiv.txt"); // Считывание файла в массив $file_array-считывается
fclose($fp);
}
else:
print "The file $file does not exist or it is not a valid file!";
endif;
echo "<br>";
$podmassiv = array_chunk($file_array,$result);//делит на подмассив
foreach ($podmassiv as $key => $value){
foreach ($value as $pers);
foreach ($peremen as $per)
if (preg_match("/^($per)$/i", $pers)){
$print = (array_values($podmassiv[$key]));}
}
echo "<ul>" ;
foreach ($print as $value) echo"<li> $value";
echo "</ul>";
?>
|
| |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 20:10)
| | foreach($a as $v) array_push($m, array_map('trim', explode(',',$v)));
обходит в цикле массив строк полученных из файла, разбивает строку на массив, убирает крайние пробелы в элементах полученного массива, и вставлят этот массив в массив $m.
Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков, а вам нужно искать фамилие, имена и т.п.. Достаточно добавить ключи в массивы и все можно решить.
А вообще, бросьте эту затею, и начинайте сразу с представления своих данных в базе, и поиска в ней. Это полезней будет, ибо ваши данные, это табличные данные. | |
|
|
|
|
|
|
|
для: sim5
(25.06.2010 в 20:38)
| | >Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков, а вам нужно искать фамилие, имена и т.п.. Достаточно добавить ключи в массивы и все можно решить.
Спасибо большое!
Так действительно проще и работает.
Но вот если получать данные из формы, не работает.( | |
|
|
|
|
|
|
|
для: Jenshina
(25.06.2010 в 23:38)
| | Не обрамляйте текст, который вы хотите процитировать, да и любой свой текст (кроме кода) ВВ-тегами [сode][/сode]. Вы же видите, что это превращается в одну строку, а прокручивать страницу по горизонтали для того чтобы прочитать, это просто неудобно. Вас за это:
а) либо обругают;
б) либо просто будут игнорировать ваши сообщения.
Если и возникает необходимость вставки простого текста (не кода) в эти теги, то разбейте его на несколько строк, при необходимости можно и отредактировать, если появляется горизонтальная прокрутка. Помните, что если на ваш пост ответили, вы уже не сможете отредактировать такую свою "портянку".
Цитируйте проще:
>Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков...
Такого вполне достаточно будет.
Это была преамбула. )
Все будет работать, если сравнивать и с данными полученными из формы. Выше я выставлял пример с формой, который работает. В этом примере можно реализовать два условия сравнения: если любое совпадение (ИЛИ), и если все (И). Единственное, что нужно учитывать, это то, что сравниваются значения массивов, и конечно, если "Вася" имеет фамилию "Люба" (очень экзотично, конечно, но а вдруг :)), то можно получить совсем не то, чего хотелось бы.
Но если применять для сравнения функцию array_intersect_assoc, которая не просто сравнивает значения элементов массива, но и соответствие их ключей, то будем получать именно то, что требуется, при этом также остается возможность задавать логику сравнения - И/ИЛИ. Для этого файл с данными должен содеражть не только записи фамилий, имен, и т.д., но и ключи, причем эти ключи должны быть такими же как и соответствующие имена полей у формы. Записывать ключ=>значение в строке конечно можно, и разбить потом эту строку на ассоциативный массив тоже можно, но лучше так не поступать. Лучше записывать в файл сериализованный массив, а для работы извлекать его и помещать в сессию, если работать с ним необходимо не на одной странице, иначе просто извлекать в переменную. Новые записи добавляются в этот массив, опять сериализация и сохранение в файл.
Кроме этого нужно учитывать еще то, что функции пересечения массивов выполняют сравнение по строгому соответствию, то есть "Вася" не будет равно "вася" (поэтому, кстати, и удаляются крайние пробелы в значениях элементов массива формы и записей в файле). Это означает, что при сравнении двух массивов, нужно, например, переводить их значения в нижний регистр (считая, что записи ключей в списке строго соответствуют именам полей формы), так как пользователь может написать имя/фамилию любым регистром в любой позиции.
Если все это соблюсти, то все будет работать, но...
Знать наличие функций работы с массивами, их назначение и возможности, это конечно очень полезно, ибо работать с массивами придется часто, хотя бы потому, что форма от пользователя, это уже массив. Прежде, чем методично перебирать такой массив, решая некую задачу, полезно заглянуть в список функций, возможно есть среди них та, что поможет решить эту задачу проще.
Это несомненно полезно, и ваши "изыскания" тоже будут полезны как пример для освоения функций работы с массивами, открытия в них "изюминок", которые явно вроде бы и не видны из описания их работы. Но для реального скрипта, который будет работать на сервере, и который должен хранить данные о человечиках, производить поиск по этим данным, выше изложенный пример никак не пойдет. Не буду вас убеждать бросить затею с массивами и с текстовым файлом, лучше уж самой убедиться в том, что такое возможно только если данных мало, да и условий поиска не много, но если все возрастет, то... Собственное понимание ошибочности рассуждения и причин ошибок гораздо весомее и полезнее, так что дерзайте.
Единственное, что можно сказать, это то, что таблица содержащая такие же самые данные, это по структуре тот же самый массив, который и в файле содержится. Но вот по удобству поиска и получения результатов его, массив с таблицей никак не сравнить, лидером в этом является таблица. Вот почему вам стоит задуматься именно над таким представлением и хранением данных. Простой пример - пользователь знает, что фамилия начинается с "Иван", но полностью или "Иванова", или "Иванчикова", или "Ивантеева", ...? И в массиве можно сделатаь такой поиск, но в случае с базой будет проще и удобнее.
И последнее - не кидайтесь в крайности, помните всегда, что разбор рег. выражениями, это затратные операции, и прежде чем их применять, посмотрите внимательно и подумайте, вполне возможно, что есть решение, которое позволит избежать их. И если есть, значит решайте задачу без них. | |
|
|
|
|