Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как удалить повторяющиеся элементы двух массивов?
 
 автор: Владимир55   (10.09.2012 в 21:58)   письмо автору
 
 

Имеется три массива $m_1, $m_2 и $m_3.

Первый массив содержит буквенно-цифровые элементы, разделенные пробелами:
$m_1[1] = “n 1 1 7”;
$m_1[2] = “9 95”;
$m_1[3] = “n 117”;
$m_1[4] = “99 5”;
$m_1[5] = “1 23”;


Элементы второго массива образованы из элементов первого массива путем удаления пробелов:
$m_2[1] = “n117”;
$m_2[2] = “995”;
$m_2[3] = “n117”;
$m_2[4] = “995”;
$m_2[5] = “123”;


Элементы третьего массива являются строками, некоторые из которых повторяются:
$m_3[1] = “молоко”;
$m_3[2] = “молоко”;
$m_3[3] = “молоко”;
$m_3[4] = “молоко свежее”;
$m_3[5] = “молоко”;


Требуется из всех массивов удалить элементы, для которых пара второй-третий массив неуникальны. Для данного примера нужно удалить элементы $m_1[1], $m_2[1] и $m_3[1] либо $m_1[3] , $m_2[3] и $m_2[3], поскольку для них одинаковы пары «n117 – молоко».

Как это сделать на РНР, без использования MySQL?

  Ответить  
 
 автор: confirm   (11.09.2012 в 01:44)   письмо автору
 
   для: Владимир55   (10.09.2012 в 21:58)
 

Не пишите кавычек таких, это ошибка в РНР и, если копировать ваши данные, то значит производить замену их.

Можно пройти циклом со сравнением, забирая только уникальные значения (как строка значений второго плюс третьего массива). Можно выполнить с помощью функций стандартных, получив уникальные ключи, а по ним необходимое. Способов много. Вот с помощью стандартных функций:
<?
$m_1 
= array("n 1 1 7""9 95""n 117""99 5""1 23");
$m_2 = array("n117""995""n117""995""123");
$m_3 = array("молоко""молоко""молоко""молоко свежее""молоко");
echo 
'<pre>';
//формируем массив уникальных значений
$a array_unique(array_map(function($a$b) {
    return 
$a.' '.$b;
}, 
$m_2$m_3));
print_r($a);
//по ключам этого массива получаем необходимые массивы из трех источников
$m_1 array_intersect_key($m_1$a);
print_r($m_1);
$m_2 array_intersect_key($m_2$a);
print_r($m_2);
$m_3 array_intersect_key($m_3$a);
print_r($m_3);
Но это ради того, чтобы знать, что можно "творить" с помощью стандартного набора, а вот на практике, все таки лучше в MySQL (надо полагать данные из нее), так как в запросе можно соединить в строку эти значения, и выбрать только уникальные записи.

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 10:02)   письмо автору
 
   для: confirm   (11.09.2012 в 01:44)
 

Не пишите кавычек таких, это ошибка в РНР
Тему в ворде писал - оттуда и такие кавычки переползли.

на практике, все таки лучше в MySQL
В MySQL это было бы удобно, но в скрипте база не используется, а подключать её только ради этого не хотелось.

К тому же, Вы создали такое элегантное решение, что так даже лучше.

Однако данный конкретный код не работает. Выводится сообщение:
Parse error: syntax error, unexpected T_FUNCTION, expecting ')' in test.php on line 7

  Ответить  
 
 автор: confirm   (11.09.2012 в 10:13)   письмо автору
 
   для: Владимир55   (11.09.2012 в 10:02)
 

Все скобки на месте, у меня ведь работает, коли я "был недоволен" ) вашими скобками, значит я копировал, а если копировал, значит запускал.
Что за версия РНР у вас?

Начиная с версии 5.3.0 всегда доступно расширение SPL, которое богато итераторами, которые для решения подобных задач (начиная с начала) куда более элегантнее.

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 11:37)   письмо автору
 
   для: confirm   (11.09.2012 в 10:13)
 

PHP Version 5.2.12.

Версии выше я применять не могу, поскольку нужен Zend Optimizer , а он в 5.3 не поддерживается.

Нет ли способа реализовать в 5.2 ?

  Ответить  
 
 автор: confirm   (11.09.2012 в 12:01)   письмо автору
 
   для: Владимир55   (11.09.2012 в 11:37)
 

Да он везде будет работать, так как нет никакой ошибки. Выполните тоже самое, но по-проще, с меньшим числом аргументов:
<?
$m 
= array("n 1 1 7""9 95""n 117""99 5""1 23"); 
echo 
'<pre>'

$a array_map//открываем скобку аргументов функции обхода массива 
      
function( //объявляем функцию являющуюся первым аргументом функции обхода массива
                //и открываем скобку перед ее аргументами
                 
$аргумент_объявленной_функции
              
//закрываем скобку после аргументов объявленной функции 
         
//открываем фигурную скобку тела объявленной функции
            
return str_replace//выполняем вложенную функцию, и открываем скобку ее аргументов
               
' ','',$аргумент_объявленной_функции
         
); //закрываем скобку аргументов вложенной функции, и закрываем строку кода
      
}, //закрываем фигурную скобку тела объявленной функции  
   
$m //второй аргумент функции обхода массива
); //закрываем скобку аргументов функции обходя массива, и закрываем строку кода

print_r($a);
В примере расписана каждая скобка. Так же можно описать и скобки примера приведенного ранее.

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 13:10)   письмо автору
 
   для: confirm   (11.09.2012 в 12:01)
 

Я тоже знаю, что все скобки на месте. Поэтому и привел диагностическое сообщение полностью, а не пересказал его.

Однако и этот, сокращенный код, не работает. Причем, ни на сервере, ни на Денвере. Диагностика та же, только относится к line 6.

Вот такая загадка...

  Ответить  
 
 автор: confirm   (11.09.2012 в 14:06)   письмо автору
 
   для: Владимир55   (11.09.2012 в 13:10)
 

Да нет ничего загадочного, надо полагать, что это связано с объявлением анонимных функций, которая и применяется в примере. Анонимные функции появились в РНР 5.3.0 (у меня версия 5.3.9). Значит в вашей версии этот пример работать не будет. Другого объяснения я не нахожу.
Для вашей версии, возможен только один выход (именно для использования этого примера), это создание анонимной функции посредством create_function, или проход массива в цикле запоминать/сравнивать.

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 14:13)   письмо автору
 
   для: confirm   (11.09.2012 в 14:06)
 

create_function, по идее, должна работать и с версией 5.2. Но я этого никогда не делал.

Можете Вы написать её для созданного Вами решения?

  Ответить  
 
 автор: confirm   (11.09.2012 в 14:23)   письмо автору
 
   для: Владимир55   (11.09.2012 в 14:13)
 

Не по идее, а будет работать, это "дедушка" объявления лямбда-функции. Замените код создание массива уникальных значений на этот:
<?
//формируем массив уникальных значений 
$a array_unique(array_map(create_function('$a, $b''return $a."  ".$b;'), $m_2$m_3));

PS. Лучше обновлять РНР, устанавливая последнюю рабочую версию, даже, если, придется слегка править код для этого (правда, если следовать рекомендациям разработчиков, то вряд ли такое придется делать).
Можно эту задачу решить с помощью итераторов. Для работы с итераторами нужно расширение SPL, которое доступно и включено по умолчанию начиная с версии PHP 5.0.0, то есть в вашей есть. Но давать пример на них я не буду, вам трудны для понимания и простые примеры (насколько можно судить), а итераторы, это "тяжелая артиллерия" для понимания, если конечно не изучать РНР (его возможности).
Или циклы, что с точки зрения производительности (в случае большого объема этих массивов) выгоднее чем цепочка функций. Но, если рассматривать задачу изначально, начиная с первоначальных данных (то есть, ваши действия: данные-->получили массив-->еще связанные данные-->результат), то вполне может быть и оправдано применение array_map/array_walk+create_function, которое бы вернуло уже готовый результат - три массива только уникальных значений.

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 16:04)   письмо автору
 
   для: confirm   (11.09.2012 в 14:23)
 

Отлично все заработало, спасибо!

Интересное, яркое решение!

  Ответить  
 
 автор: Valick   (11.09.2012 в 15:11)   письмо автору
 
   для: Владимир55   (10.09.2012 в 21:58)
 

Изначальные и ключевые массивы, я так понимаю, 1 и 3, а массив номер 2 вспомогательный и в конечном итоге нужно получить 1 и 3 массив без повторений связанных строк.
Для полного понимания ситуации расскажите как формируются массивы 1 и 3, на мой взгляд несколько странное хранение данных или это тоже промежуточный результат?

  Ответить  
 
 автор: Владимир55   (11.09.2012 в 16:03)   письмо автору
 
   для: Valick   (11.09.2012 в 15:11)
 

Изначальные и ключевые массивы, я так понимаю, 1 и 3, а массив номер 2 вспомогательный и в конечном итоге нужно получить 1 и 3 массив без повторений связанных строк.

Так и есть.

как формируются массивы 1 и 3, на мой взгляд несколько странное хранение данных или это тоже промежуточный результат?

Это окончательный результат.
Данные приходят из удаленной базы и они явялются таким по той причине, что владельцы базы их собирали из каталогов производителей разных стран. Кто что наисал, то и хранится в их базе.

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

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования