у меня 2 массива
$arr1 = Array (
[0] => Array ( [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1 )
[1] => Array ( [customer_id] => 2 [Expire] => 2019-06-20 [paid] => 0 ))
а также
$arr2 = Array (
[0] => Array ( [id] => 3943 [customer_id] => 1 [Expire] => 2019-05-14 )
[1] => Array ( [id] => 3944 [customer_id] => 1[Expire] => 2019-05-14 )
[2] => Array ( [id] => 4713 [customer_id] => 2 [Expire] => 2019-06-20 )
)
и попробуйте поместить ключ первого массива и значение [paid] => 1 или 0 во второй массив, если идентификатор клиента и срок действия совпадают, например
Array (
[0] => Array ( [id] => 3943 [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1)
[1] => Array ( [id] => 3944 [customer_id] => 1 [Expire] => 2019-05-14 [paid] => 1)
[2] => Array ( [id] => 4713 [customer_id] => 2 [Expire] => 2019-06-20 [paid] => 0)
)
Я пытаюсь объединить массив в php, но не получаю того, что хочу. Есть ли какая-нибудь функция php для этого?
Можете ли вы сделать индекс массива как customer_id вместо 0,1,2..etc? Это сделает вещи намного проще
значение customer_id не может быть 0
Лучше всего показать нам, что вы пробовали, и сказать, где что-то идет не так. @Qirel Оскорбительный идентификатор был удален Deepak3301086 пять минут назад.
иногда можно сделать что-то сложное :)
<?php
$arr1 = [
['customer_id' => 1, 'Expire' => '2019-05-14', 'paid' => 1],
['customer_id' => 2, 'Expire' => '2019-06-20', 'paid' => 0],
];
$arr2 = [
['id' => 3943, 'customer_id' => 1, 'Expire' => '2019-05-14'],
['id' => 3944, 'customer_id' => 1, 'Expire' => '2019-05-14'],
['id' => 3945, 'customer_id' => 2, 'Expire' => '2019-05-14'],
['id' => 4713, 'customer_id' => 2, 'Expire' => '2019-06-20'],
];
foreach ($arr2 as &$item2) {
foreach ($arr1 as $item1) {
if (
$item2['customer_id'] === $item1['customer_id']
&& $item2['Expire'] === $item1['Expire']
) {
$item2['paid'] = $item1['paid'];
break;
}
}
}
unset($item2);
var_dump($arr2);
Я думаю, что тройка ===
, равная «Идентичный оператор», здесь чрезмерна. Двойное ==
равно «Оператор равенства». Мне действительно было бы все равно, был ли «id» 3943
(целое число) или "3943"
(строка), более того, я бы подумал, что они равны и должны рассматриваться как таковые.
Это может решить проблему:
$arr1 = array(
["customer_id"=>1,"Expire"=> "2019-05-14", "paid"=>1],
["customer_id"=>2,"Expire"=> "2019-06-20", "paid"=>0]
);
$arr2 = array(
["id"=>3943, "customer_id"=>1,"Expire"=> "2019-05-14"],
["id"=>3944,"customer_id"=>2,"Expire"=> "2019-06-20"],
["id"=>4713,"customer_id"=>1,"Expire"=> "2019-05-14"]
);
$result= array();
function getRowByCustomerID($id, $array){
foreach($array as $value){
if ($value['customer_id'] ==$id){
return $value;
}
}
return null;
}
foreach($arr2 as $subarr){
$object = getRowByCustomerID($subarr['customer_id'],$arr1 );
if (!is_null($object)){
$object['id']=$subarr['id'];
$result[]= $object;
}
}
var_dump($result);
вывод аналогичен тому, что вы ищете:
array(3) {
[0]=>
array(4) {
["customer_id"]=>
int(1)
["Expire"]=>
string(10) "2019-05-14"
["paid"]=>
int(1)
["id"]=>
int(3943)
}
[1]=>
array(4) {
["customer_id"]=>
int(2)
["Expire"]=>
string(10) "2019-06-20"
["paid"]=>
int(0)
["id"]=>
int(3944)
}
[2]=>
array(4) {
["customer_id"]=>
int(1)
["Expire"]=>
string(10) "2019-05-14"
["paid"]=>
int(1)
["id"]=>
int(4713)
}
}
Ваш $arr2
не такой, как в вопросе. Смотрите «платные» ключи.
вы правы, я просто обновляю свой ответ, это не повредит результату. спасибо @KIKOSoftware
Если вы не можете изменить макет первого массива, я думаю, будет лучше сначала создать промежуточный массив, в котором будут храниться записи всех дат истечения срока действия для каждого клиента.
Следующая реализация не требует использования вложенного цикла.
<?php
$arr1 = [
['customer_id' => 1, 'Expire' => '2019-05-14', 'paid' => 1],
['customer_id' => 2, 'Expire' => '2019-06-20', 'paid' => 0],
];
$arr2 = [
['id' => 3943, 'customer_id' => 1, 'Expire' => '2019-05-14'],
['id' => 3944, 'customer_id' => 1, 'Expire' => '2019-05-14'],
['id' => 3945, 'customer_id' => 2, 'Expire' => '2019-05-14'],
['id' => 4713, 'customer_id' => 2, 'Expire' => '2019-06-20'],
];
// Create a list of all paid, expiry dates, keyed by customer_id
$payed = [];
foreach ($arr1 as $item) {
if (!isset($payed[$item['customer_id']])) {
$payed[$item['customer_id']] = [];
}
$payed[$item['customer_id']][] = $item['Expire'];
}
// Lookup the customer and expire date for every entry
$arr2 = array_map(function($item) use ($payed) {
$item['paid'] = in_array($item['Expire'], $payed[$item['customer_id']] ?? []);
return $item;
}, $arr2);
Результат:
Array
(
[0] => Array
(
[id] => 3943
[customer_id] => 1
[Expire] => 2019-05-14
[paid] => 1
)
[1] => Array
(
[id] => 3944
[customer_id] => 1
[Expire] => 2019-05-14
[paid] => 1
)
[2] => Array
(
[id] => 3945
[customer_id] => 2
[Expire] => 2019-05-14
[paid] =>
)
[3] => Array
(
[id] => 4713
[customer_id] => 2
[Expire] => 2019-06-20
[paid] => 1
)
)
Зациклите свой второй массив $arr2
и найдите индекс первого массива $arr1
, где столбец customer_id
такой же, как в текущей итерации $arr2
. array_search()
возвращает этот индекс, который мы затем можем использовать для получения индекса paid
этого массива. Затем мы добавляем его в наш массив $arr2
, выполнив $a['paid'] = $paid;
.
Поскольку мы зацикливаем массив по ссылке (&
перед $a
в цикле), внесенные в него изменения будут применены обратно к исходному массиву.
foreach ($arr2 as &$a) {
$customerID = $a['customer_id']; // This customer ID
$arr1_key = array_search($customerID, array_column($arr1, 'customer_id')); // Find the index of this customerID in the first array
$paid = $arr1[$arr1_key]['paid']; // Find the paid value matching that customer ID
$a['paid'] = $paid;
}
Обновлять
Если вам нужно, чтобы он соответствовал идентификатору, а также дате истечения срока действия, используйте array_filter()
для получения элемента массива в $arr1
, который соответствует дате и идентификатору. Используя reset()
, мы используем первый элемент в этом массиве.
foreach ($arr2 as &$a) {
// Find the sub-array of $arr1 that matches this array's date and ID
$arr1_match = array_filter($arr1, function($v) use ($a) {
return $v['customer_id'] == $a['customer_id'] && $v['Expire'] == $a['Expire'];
});
// Get the first element from the result
$paid = reset($arr1_match)['paid'];
// Append the paid-value to this array (done by reference)
$a['paid'] = $paid;
}
Это, конечно, хорошее решение. Просто хочу отметить, что вы могли бы сделать это наоборот: foreach ($arr1 as
и выполнить поиск в столбце $arr2
. Почему? Потому что кажется, что $arr1
— это информация о входящем платеже, а $arr2
— существующий список клиентов. Я бы также поместил array_column($arr1, 'customer_id')
вне цикла foreach
. Но эй, это мелкие детали, это, безусловно, лучшее решение. Вы получаете мой голос.
Хм, вполне может быть. Проблема в том, что во втором массиве есть несколько экземпляров каждого идентификатора клиента, но только один в первом. В первом массиве также меньше записей, чем во втором. Это означает, что получить желаемый результат будет немного сложнее (это означает, что вы не можете использовать приведенный выше фрагмент, просто заменив $arr1
на $arr2
и наоборот). Вы, вероятно, правы насчет определений массивов.
Да, я только что понял это. Это заставляет вас делать это таким образом. Было бы лучше, если бы массивы в вопросе имели собственные имена, такие как $payments
, $customers
или $orders
, что дало бы вам лучшее представление о том, с чем вы имеете дело.
Спасибо, это работа для меня. Это экономит время второго цикла.
Это работает только для совпадения идентификатора клиента, если дата отличается, это не работает. Пожалуйста, проверьте 3v4l.org/TeTpK
Нужно найти индекс обоих (customer_id и Expire). затем сопоставьте оба индекса, если они совпадают, то поставьте платное значение.
Затем используйте array_filter()
, чтобы получить правильный подмассив в $arr1
. Смотрите пересмотренный ответ.
Что случилось с идентификатором 3945, customer_id 2? Почему этого нет в конечном желаемом результате?