merging array in CI 3 - php

I want to merge two arrays in order to get the data as per my requirement.
I am posting my result, please have a look.
First array:
Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
)
)
Second array:
Array
(
[0] => Array
(
[user_id] => 9c2e00508cb28eeb1023ef774b122e86
[car_id] => 14783
[status] => favourite
)
)
I want to merge the second array into the first one, where the value at key car_id matches the equivalent value; otherwise it will return that field as null.
Required output:
<pre>Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
[fav_status] => favourite
)
)

Since the merge is so specific I would try something like this:
foreach ($array1 as $index => $a1):
foreach ($array2 as $a2):
if ($a1['car_id'] == $a2['car_id']):
if ($a2['status'] == "favourite"):
$array1[$index]['fav_status'] = "favourite";
endif;
endif;
endforeach;
endforeach;
You might be able to optimize the code more but this should be very easy to follow...

Another way to achieve this without using the index syntax is to reference the array elements in the foreach by-reference by prepending the ampersand operator:
foreach($firstArray as &$nestedArray1) {
foreach($secondArray as $nestedArray2) {
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1['fav_status'] = $nestedArray2['status'];
}
}
}
You can see it in action in this Playground example.
Technically you asked about merging the arrays. While the keys would be different between the input arrays and the desired output (i.e. "status" vs "fav_status"), array_merge() can be used to merge the arrays.
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 = array_merge($nestedArray1, $nestedArray2);
}
Playground example.
Additionally the union operators (i.e. +, +=) can be used.
If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator1
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 += nestedArray1;
}
Playground example.
1http://php.net/manual/en/function.array-merge.php#example-5587

Related

Deleting complex array element

So I want to delete an array element from a JSON array based on an id in a sub-array. I know it sounds weird. Here's an example of the array. I want to delete the entire array [0] based on the [dealer][id] array where the [id] = 20220 in this example.
Array
(
[results] => Array
(
[offset] => 1
[length] => 15
[data] => Array
(
[0] => Array
(
[dealer] => Array
(
[id] => 20220
[name] => apple
)
)
)
)
}
In reality there are a lot more elements in the [results] array. I'm not sure how to go about it.
Any help is greatly appreciated!
Loop thru data key first then check if dealer id matches the searched id
$id = 20220;
foreach ($array['results']['data'] as $key => $value) {
if ($value['dealer']['id'] == $id) {
unset($array['results']['data'][$key]);
}
}
use array_filter,
$array['results']['data'] = array_filter($array['results']['data'], function($v){return $v['dealer']['id'] != 20220;});

checking condition in multi dimensional array

I want to check a multi dimensional array for a key value and print its parent array's another key value. This might confuse a bit. But the below example can make it clear. I have a array like this.
Entity Response : Array
(
[0] => Array
(
[type] => FieldTerminology
[relevance] => 0.709023
[count] => 4
[text] => domain name
)
[1] => Array
(
[type] => Company
[relevance] => 0.603375
[count] => 2
[text] => Laravel
)
[2] => Array
(
[type] => Person
[relevance] => 0.548389
[count] => 1
[text] => M. Naveen Kumar
)
I want to check if any array has a key [type] and its value = "Person" , then i want to get its value of the key[text]. In this case I want to print M. Naveen Kumar
You can traverse the array to find it. you can use foreach(), array_walk() and so on.
$o = [];
array_walk($array, function($v) useļ¼ˆ&$o){$v['type'] == 'Person' ? $o[] = $v['text'] : '';});
var_dump($o);
Try this
$people = array_filter($array, function($each) { return $each['type'] == 'Person'; });
$names = array_map(function($each) { return $each['name']; }, $people);
How does this work step by step?
Filter the array by type using array_filter
Then map to names using array_map

Intersect (inner join) two arrays with different key names

I have following two multidimensional arrays:
First array:
$array_1_data = Array (
[0] => Array ( [id] => 1 [name] => IT [slug] => it )
[1] => Array ( [id] => 2 [name] => Accounting [slug] => accounting )
)
Second array:
$array_2_data = Array (
[0] => Array ( [cid] => 3 [jid] => 24061 )
[1] => Array ( [cid] => 1 [jid] => 24062 )
)
Expected result:
$some_array = Array (
[0] => Array ( [id] => 1 [name] => IT [slug] => it )
)
I won't mind having [cid] in the result.
I want to intersect these two arrays by [id] of the first array and [cid] of the second array, like inner join in MySQL. I have basic foreach and if else logic for this purpose but speed is a priority now so I'm looking for non-looped solution. For better understanding here is the basic looped solution:
foreach ($array_1_data as $array_1_row ) {
foreach ($array_2_data as $array_2_row ) {
if ($array_2_row['cid'] == $array_1_row['id']) {
//intersection iteration
}
}
}
I tried array_uintersection as follows:
array_uintersect($array_1_data, $array_2_data, function($a1, $a2){
$diff1 = strcasecmp($a1['id'], $a2['cid']);
if ($diff1 != 0) return $diff1;
return 0;
});
But it gives me undefined index 'id'. I checked this question: Comparing two arrays with different key names. First answer for this question gives a looped solution which I want to avoid. Second answer suggests changing SQL structure but I have no control over that. So,
Is there really a non-looped fast solution to this kind of situation?
The solution using array_uintersect_uassoc function:
$result = array_uintersect_uassoc($array_1_data, $array_2_data, function($a, $b){
return strcasecmp($a['id'], $b['cid']);
}, function($a, $b){
return (int) [$a, $b] == ['id', 'cid'];
});
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[name] => IT
[slug] => it
)
)
According yo your condition: to intersect these two arrays by [id] of the first array and [cid] of the second array, we should consider a key comparison function for those keys only ['id', 'cid'].
Having the needed keys on each comparison step it only remain to compare their values(with value compare function)
http://php.net/manual/en/function.array-uintersect-uassoc.php
DEMO link

Array_Unique filtering

I have an multidimensional array:
Array
(
[0] => Array
(
[Id] => 1
[MTime_Id] => 1
[MName] => Breakfast
[DName] => Other Cereals
[IName] =>
[Date] => 2013-02-05
)
[1] => Array
(
[Id] => 1
[MTime_Id] => 1
[MName] => Breakfast
[DName] => Porridge
[IName] => Oats,Milk,Sugar
[Date] => 2013-02-06
)
[2] => Array
(
[Id] => 1
[MTime_Id] => 1
[MName] => Breakfast
[DName] => Porridge
[IName] => Oats,Milk,Sugar,Oats,Milk,Sugar
[Date] => 2013-02-05
)
)
And I am trying to use array unique to filter this
[IName] => Oats,Milk,Sugar,Oats,Milk,Sugar
I am having no luck. How can I filter the duplicates?
Cheers.
If you filter input and therefore don't have extra spaces in IName field, you can use something as simple as this for filtering:
$array[2]['IName'] = implode(',', array_unique(explode(',', $array[2]['IName'])));
The problem is that you habe in array two Oats,Milk,Sugar as element of IName, in array three you have Oats,Milk,Sugar,Oats,Milk,Sugar. This is not the same!
"Oats,Milk,Sugar"=="Oats,Milk,Sugar,Oats,Milk,Sugar" (or "Oats,Milk,Sugar".equals("Oats,Milk,Sugar,Oats,Milk,Sugar")) is false.
If you want to have it unique you have to explode the single results and then do a unique on it or you have to store the single values in seperate fields...
BTW: Here is a link how to remove duplicates from a multi dimensional array How to remove duplicate values from a multi-dimensional array in PHP
I am not sure if a function exists for that, here is a simple solution,
you can loop the array, and get the result of each value, then explode result, and insert it into an array.
then use the array_unique function.
try this:
$result = array();
foreach($arrays as $array)
{
$tmp = $array['IName'];
$tmp2 = explode(',',$tmp);
foreach ($tmp2 as $t)
{
$result[]=$t;
}
}
$array_unique = array_unique($result);

Most Efficient Way to Delete Nested Array Element

Say I have the following:
Array(
[0] => Array
(
[id] => 1
[item] => first item
)
[1] => Array
(
[id] => 3
[item] => second item
)
[2] => Array
(
[id] => 5
[item] => third item
)
)
I want to delete the item with id = 5. I know I can loop through the array and unset, but I'm hoping for a more direct/efficient solution.
If you cannot make the IDs the keys of the outer array (then you could simply use unset($arr[5]);), looping over the array is indeed the way to dg.
foreach($arr as $key => $value) {
if($value['id'] === 5) {
unset($arr[$key]);
break;
}
}
Another option would be using array_filter - that's less efficient though since it creates a new array:
$arr = array_filter($arr, function($value) {
return $value['id'] !== 5;
});
Why don't you create the array with the keys set as the ID's? E.g:
Array(
[1] => Array
(
[id] => 1
[item] => first item
)
[3] => Array
(
[id] => 3
[item] => second item
)
[5] => Array
(
[id] => 5
[item] => third item
)
)
You can then write:
<?php
unset($array[5]); // Delete ID5
?>
For Multi level nested array
<?php
function remove_array_by_key($key,$nestedArray){
foreach($nestedArray as $k=>$v){
if(is_array($v)){
remove_array_by_key($key,$v);
} elseif($k==$key){
unset($nesterArray[$k]);
}
}
return $nestedArrat;
}
?>
The most efficient way would be to have 2 arrays.
ID => Index
Index => Object (your current array)
Search for ID in your ID => Index helper array and the value will be the Index for your main array, then unset them both.

Categories