Update an array with fields from matching array - php

I have Array1 that pulls all of the entries for a Wordpress custom post type, and I have Array2 from another table that shows if that post type has been seen by a specific user. If the ID of Array1 & the PageID of Array2 are the same, then add the [Started] & [Finished] fields from Array2 to Array1. Basically I want to combine them to form Array3. I have tried many different solutions with array_combine but can't get the result I'm looking for.
Array1 (
[0] => stdClass Object ( [ID] => 75 [post_title] => Test Training Video )
[1] => stdClass Object ( [ID] => 80 [post_title] => Test 2 )
[2] => stdClass Object ( [ID] => 85 [post_title] => Test 2 ) )
Array2 (
[0] => stdClass Object ( [PageID] => 75 [Started] => 1 [Finished] => 1 )
[0] => stdClass Object ( [PageID] => 80 [Started] => 1 [Finished] => 0 ) )
Array3 (
[0] => stdClass Object ( [ID] => 75 [post_title] => Test Training Video [Started] => 1 [Finished] => 1 )
[1] => stdClass Object ( [ID] => 80 [post_title] => Test 2 [Started] => 1 [Finished] => 0 )
[2] => stdClass Object ( [ID] => 85 [post_title] => Test 2 ) )

Something like this?
$array3 = array();
foreach( $array1 as $arr1 )
{
foreach( $array2 as $arr2 )
{
if( $arr1["ID"] == $arr2["PageID"] )
{
$array3[] = array( $arr1["Started"], $arr2["Finished"] );
}
}
}

array_combine() is not the right function for this.
In your case, you need to use a foreach-loop to loop over the values of your first array and compare them with your second array.
You also need to rearrange array 2, so that you can easily access the values for started and finished using the pageID as key:
$pageMap = array();
foreach($array2 as $entry) {
$pageMap[$entry['PageID']] = array('started' => $entry['Started'], 'finished' => $entry['Finished']);
}
Then you can do:
$combined_array = array();
foreach($array1 as $post) {
if(!isset($pageMap[$post['ID']])) continue; // do nothing if there are no started/finished entries.
$combined_array[$post['ID']] = array_merge($post, $pageMap[$post['ID']]);
}

You could try a first loop to make your array "ID" match and then combine both arrays
foreach( $array2 as $key=>$value )
{
$value['ID'] = $value['PageId'];
unset($value['PageId']);
$array2[$key] = $value;
}
$array3 = array_merge_recursive($array1,$array2);

After trying the posted solutions I decided to make the change in my $wpdb->get_results sql statement instead of using 2 different sql statements and then combining the 2 different arrays. With help from this post - SQL query to join two tables despite the other table may not have values, I was able to use the following to get the desired result.
$oneBigQuery = $wpdb->get_results("SELECT a.ID, a.post_title, b.PageID, b.Started, b.Finished
FROM $wpdb->posts AS a
LEFT JOIN exampleTableName AS b
ON a.ID = b.PageID
AND b.UserID = 3
WHERE a.post_type = 'custom-post-type'
");

Related

merging array in CI 3

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

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

PHP array not setting custom key in a foreach loop

I'm looping through a database object returned by MySQL in CodeIgniter 2.x (PHP). The array $gifts has been declared outside the loop before it begins.
There is an inner loop and an outer loop. The outer loop generates the second array example below. The inner loop generates the problem array.
In LINE 2, $i['gifts'][$row->id_gift] correctly setting the keys with the desired id $row->id_gift. In LINE 1, it is not. The array key is being assigned numerically in order from 0-n as if it were being set with $gifts[][$sd] = $row->$sd.
Any thoughts on why?
$query = $this->db->get();
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
foreach ($select_details as $sd)
{
$gifts[$row->id_gift][$sd] = $row->$sd; // LINE 1
$i['gifts'][$row->id_gift] = array('merchant_rank'=>$i['merchant_rank'],'rank'=>$row->rank); // LINE 2
}
}
}
$select_details = array('id_gift','id_group','rank');
Array (LINE 1) output sample:
Array (
[0] =>
Array (
[id_gift] => 392
[id_group] => 244
[rank] => 1
)
[1] => Array (
[id_gift] => 287
[id_group] => 239
[rank] => 1
)
[2] => Array (
[id_gift] => 264
[id_group] => 4
[rank] => 1)
)
Array (LINE 2) output sample (note the correct keys in the gifts array):
Array (
[0] => Array
(
[id] => 49
[id_group] => 49
[id_merchants] => 116
[gifts] => Array
(
[392] => Array
(
[merchant_rank] => 1
[rank] => 1
)
[287] => Array
(
[merchant_rank] => 1
[rank] => 2
)
[264] => Array
(
[merchant_rank] => 1
[rank] => 3
)
)
)
)
RESOLVED. See my answer below if you're curious. Thanks for your help #Spartan and #DontPanic.
Okay, I figured out the problem. And the more experienced programmers among you might not be all that surprised.
Later in the script I'm using a multidimensional array sort that's destroying the keys. I'm sure there's a way to prevent that, but that's not pertinent here.
usort($gifts, function($a, $b) {
return $a['rank'] - $b['rank'];
});

Create from an array who have multiple arrays - only one key => value

I have a big problem and I can't resolve it,
So I have my array :
Array
(
[0] => Array
(
[id] => 34
[groupe_id] => 4
[object_id] => 4
)
[1] => Array
(
[id] => 35
[groupe_id] => 4
[object_id] => 5
)
)
Now I want to create another array call $test for get the array in this forme:
Array
(
[object_id] = 4
[object_id] = 5
)
I tried but no results:
$test = array();
foreach($aObjectsGroupe as $object){
$test[] = array(
'object_id' => $object['object_id']
);
}
You can't have duplicates of the same key in a PHP array. It kind of defeats the purpose of keys. I can't think of a reason to have identical keys, as you would be unable to reference an individual element of the array by key anyways, because there are more than one.
Why not just make an array called $object_ids, and just have a normal indexed array of the all of the object_ids from the other array?
$object_ids = array();
foreach ($aObjectsGroupe as $object) {
$object_ids[] = $object['object_id'];
}

PHP Combining arrays with std class

This is what I want but cant figure out how to.
$a is this array
PHP Code:
Array
(
[0] => stdClass Object
(
[id] => i1
[cat] => Test1
)
[1] => stdClass Object
(
[id] => i2
[cat] => Test2
)
[2] => stdClass Object
(
[id] => i3
[cat] => Test3
)
[3] => stdClass Object
(
[id] => i4
[cat] => Test4
)
}
This is the array and it has those std classes associated with it. What I am trying to do is to combine all the "cat" names into one array variable.
I want to make $categories an array with all these "cat" as the array values.
How can I do that ?
array_map($a, function(stdClass $o) { return $o->cat; });
A simple way is just to loop over the array, grabbing the values that you want. There are other, fancier ways of doing the same but I like to keep it simple.
$categories = array();
foreach ($a as $obj) {
$categories[] = $obj->cat;
}
Of course, if not all of the array items are that object then it might be worthwhile to check that the cat property exists (and that $obj is a stdClass!).
Simply loop through and create a new array...
<?php
$newArray = array();
foreach($a as $cat) {
$newArray[$cat->id] = $cat->cat;
}
var_dump($newArray);

Categories