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
Форумы портала PHP.SU :: Версия для печати :: Выбор данных, совпадающих из двух массивов. Как ускорить?
Форумы портала PHP.SU » » Вопросы новичков » Выбор данных, совпадающих из двух массивов. Как ускорить?

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

1. LShark - 27 Января, 2013 - 16:46:27 - перейти к сообщению
Есть 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

Но как сравнить?
2. LShark - 27 Января, 2013 - 20:52:57 - перейти к сообщению
Неужели нет более скоростных алгоритмов? Хм... не верю.
3. EuGen - 27 Января, 2013 - 21:17:56 - перейти к сообщению
У Вас сравнение по совпадению первой части - или по индексу массива? Если второе, то достаточно быстро отработает конструкция наподобие
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)
Если же данные меняются часто, то такое преобразование может и не дать желаемого прироста - тут все зависит от числа итераций, которые происходят при загрузке. Возможно, некоторый прирост в быстродействии такое приготовление данных и даст, но улучшения сложности алгоритма, думаю, не произойдет.
4. LShark - 27 Января, 2013 - 21:32:21 - перейти к сообщению
Вроде нашел алгоритм:
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? Только форичем?
5. etoYA - 27 Января, 2013 - 22:00:23 - перейти к сообщению
А чем форич не подходит?
6. LShark - 28 Января, 2013 - 14:03:45 - перейти к сообщению
В целом - всем подходит. Просто вдруг есть оператор, позволяющий выдернуть из первого массива строки, используя как индекс значения второго массива?

Так как
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 при повторных.

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

 

Powered by ExBB FM 1.0 RC1