Допустим ситуацию. Есть два вложенных ассоциативных массива данных. Нужно узнать, есть ли у них "похожие" записи, учитывая при сравнении похожести значения только некоторые из ключей. Я проиллюстрирую:
// при сравнении обращаем внимание только на ключи массива `param1` и `param2`
// то есть $data[0] похожа по значимым ключам $data_src[2]
// а так же $data[1] похожа $data_src[3]
$data_src = array(
0 => array('id' => 1, 'param1' => 0, 'param2' => 0, 'value' => 0.01),
1 => array('id' => 2, 'param1' => 1, 'param2' => 0, 'value' => 0.02),
2 => array('id' => 3, 'param1' => 0, 'param2' => 1, 'value' => 0.03),
3 => array('id' => 4, 'param1' => 1, 'param2' => 1, 'value' => 0.04)
);
$data = array(
0 => array('param1' => 0, 'param2' => 1, 'value' => 0.11),
1 => array('param1' => 1, 'param2' => 1, 'value' => 0.12)
);
В моём случае я столкнулся с необходимостью такого анализа, когда писал парсер (распознавалку) файлов с прайс-листами. Там цена зависела сразу от нескольких параметров и мне нужно было запросить все цены прайса, уже существующие в базе данных и сравнить их с новыми ценами. Потом по результатам разобраться, какие вставлять, какие обновлять, какие даже удалять (если они существовали в БД, а в импортируемом файле цен с таким набором параметров уже не было).Самым очевидным (для меня) было "проиндексировать" значения этих значимых ключей, и потом искать совпадение по этой индексированной строке:
// индексируем исходный массив
$index_src = array();
foreach ($data_src as $i => $row) {
$index_src[$i] = serialize(array(
'param1' => $row['param1'],
'param2' => $row['param2']
));
}
$index_src = array_flip($index_src);
// ищем совпадения
$similar = array();
foreach ($data as $i => $row) {
$str = serialize(array(
'param1' => $row['param1'],
'param2' => $row['param2']
));
if (array_key_exists($str, $index_src)) {
$similar[$i] = $index_src[$str];
}
}
// получаем массив с индексами похожих массивов
// $similar = array(
// 0 => 2,
// 1 => 3
// );
Цель достигнута конечно, но меня не отпускает ощущение, что это не самое оптимальное решение. Хотя не спорю, по рукам нужно бить линейкой за поиск оптимального решения в задаче, выполняемой в лучшем случае раз в месяц.
Немає коментарів :
Дописати коментар