Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Выбор данных, совпадающих из двух массивов. Как ускорить?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: просто - это перебор через foreach. Но можно ли быстрее?
LShark
Отправлено: 27 Января, 2013 - 16:46:27
Post Id



Частый гость


Покинул форум
Сообщений всего: 240
Дата рег-ции: Нояб. 2012  


Помог: 1 раз(а)




Есть 2 массива.
В одном - номера и названия - например:
0 => 00 Параметр1
1 => 01 Параметр2
2 => 02 Параметр3
3 => 04 Параметр5
4 => 03 Параметр4
5 => 05 Параметр6
6 => 07 Параметр8
7 => 06 Параметр7

Есть второй - в котором просто перечислены номера пунктов:
0 => 03
1 => 04
2 => 02
3 => 09

Как из первого быстрее выбрать названия "Параметр...", соответствующие значениям второго массива?

Простой способ - через foreach перебирать первый массив, проверяя, подходит ли очередное значение второго массива (т.е. найдет значения дял 03, 04, 02 и пропустит под 09, так как такого нет в первом массиве).

НО!
В первом массиве около 100 значений.
Во втором - может быть от 1 до 100.

Сколько же переборов придется сделать? Если 99 значений во втором, то будет выполнено до 9к сравнений (реально, конечно, меньше, так как если нашлось - далее не проверяем).

Но плохо еще то, что на странице таких блоков может быть до 40 (хотя Массив1 у всех один, но Массив2 в каждом случае свой с разным количеством значений).

Есть ли более простой способ выбрать из первого массива значения, совпадающие со вторым?

Можно, конечно, разбить первый массив на два параметра:
0 => [0] = 00, [1] = Параметр1
1 => [0] = 01, [1] = Параметр2

Но как сравнить?

(Отредактировано автором: 27 Января, 2013 - 16:48:06)



-----
Истина прежде всего в том, что...
 
 Top
LShark
Отправлено: 27 Января, 2013 - 20:52:57
Post Id



Частый гость


Покинул форум
Сообщений всего: 240
Дата рег-ции: Нояб. 2012  


Помог: 1 раз(а)




Неужели нет более скоростных алгоритмов? Хм... не верю.


-----
Истина прежде всего в том, что...
 
 Top
EuGen Администратор
Отправлено: 27 Января, 2013 - 21:17:56
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




У Вас сравнение по совпадению первой части - или по индексу массива? Если второе, то достаточно быстро отработает конструкция наподобие
PHP:
скопировать код в буфер обмена
  1. $rgParameters = array(
  2. 0 => '00 Параметр1',
  3. 1 => '01 Параметр2',
  4. 2 => '02 Параметр3',
  5. 3 => '04 Параметр5',
  6. 4 => '03 Параметр4',
  7. 5 => '05 Параметр6',
  8. 6 => '07 Параметр8',
  9. 7 => '06 Параметр7'
  10. );
  11. $rgIndexes=array(
  12. 0 => '03'
  13. 1 => '04'
  14. 2 => '02'
  15. 3 => '09'
  16. );
  17. $rgResult=array_intersect_key($rgParameters, $rgIndexes);

- но вот если имеется ввиду требование поискать строки, начинающиеся на значения, указанные во втором массиве, то здесь уже нужно смотреть по ситуации. Если поиск повторяется многократно при относительно редкой смене данных, то логично привести данные в соответствие виду, когда можно сравнивать на прямое равенство и затем снова использовать array_intersect (или же array_intersect_key)
Если же данные меняются часто, то такое преобразование может и не дать желаемого прироста - тут все зависит от числа итераций, которые происходят при загрузке. Возможно, некоторый прирост в быстродействии такое приготовление данных и даст, но улучшения сложности алгоритма, думаю, не произойдет.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
LShark
Отправлено: 27 Января, 2013 - 21:32:21
Post Id



Частый гость


Покинул форум
Сообщений всего: 240
Дата рег-ции: Нояб. 2012  


Помог: 1 раз(а)




Вроде нашел алгоритм:
PHP:
скопировать код в буфер обмена
  1. $a=file("../kaf.info"); //Читаю первый массив из файла
  2. foreach($a as $key =>$value){ //Создаю новый массив, имеющий отдельно только ключи для сравнения
  3. $b[$key]=substr($value,0,2);
  4. }


А далее второй массив форичем перебираю, получая индексы совпадения. Их использую во втором массиве, получая полную строку, например:

(Добавление)
Как вариант:
$с=(array_intersect($b, $d)); //где d - это второй массив

Тогда в $c получаю ключи совпадения. Есть способ по этим ключам получить соответствующие этим ключам значения из Первого массива?

т.е. у меня на выходе:
$c = array(1,4,6,26);
Как теперь получить из первого массива значения с ключами 1, 4, 6, 26? Только форичем?


-----
Истина прежде всего в том, что...
 
 Top
etoYA
Отправлено: 27 Января, 2013 - 22:00:23
Post Id



Участник


Покинул форум
Сообщений всего: 1859
Дата рег-ции: Июль 2011  
Откуда: Крым


Помог: 21 раз(а)




А чем форич не подходит?

(Отредактировано автором: 27 Января, 2013 - 22:03:16)

 
 Top
LShark
Отправлено: 28 Января, 2013 - 14:03:45
Post Id



Частый гость


Покинул форум
Сообщений всего: 240
Дата рег-ции: Нояб. 2012  


Помог: 1 раз(а)




В целом - всем подходит. Просто вдруг есть оператор, позволяющий выдернуть из первого массива строки, используя как индекс значения второго массива?

Так как
PHP:
скопировать код в буфер обмена
  1. =(array_intersect($b, $d)); //где d - это второй массив

Как раз такой второй массив и создает.

А иначе, возможно, проще использовать первый вариант:
foreach по массиву с последующим
PHP:
скопировать код в буфер обмена
  1. $c=array_search("что_надо_найти",$b);
  2. echo $a[$c];


Сейчас буду экспериментировать, что жрет меньше ресурсов при максимально возможных вариантах (когда во втором массиве 99 пунктов для поиска из 100).
(Добавление)
Понятно.

Получается, что вариант:
$c=array_intersect($spisok_b, $pokaz);
foreach($c as $key =>$value) {
$adnod[$dn1].= $spisok[$key]."<br>";
}
выполняется при первом запуске 0,00412 (в среднем) и 0,00327 при повторных запусках.

вариант, использующий сразу перебор через
array_search - 0,00616 при первом и 0,00412 при повторных проходах.

И это при 1 блоке в 99 вариантов.

Уже при 3-х блоках:
array_search при первом проходе занимает уже 0.01052 sec и 0,00754 при повторных, а приведенный вариант:
0,00669 при первом и 0,00458 при повторных.

Вопрос решен.

(Отредактировано автором: 28 Января, 2013 - 14:38:28)



-----
Истина прежде всего в том, что...
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB