Merging multiple multidimensional arrays - php

I have a variable number of multidimensional arrays but all with the same 4 possible values for each item.
For example:
Array
(
[companyid] => 1
[employeeid] => 1
[role] => "Something"
[name] => "Something"
)
but every array may have a different ammount of items inside it.
I want to turn all the arrays into one single table with lots of rows. I tried array_merge() but I end up with a table with 8, 12, 16... columns instead of more rows.
So... any ideas?
Thanks

Didn't test it, but you could try the following:
$table = array();
$columns = array('companyid' => '', 'employeeid' => '', 'role' => '', 'name' => '');
foreach($array as $item) {
$table[] = array_merge($columns, $item);
}
This should work since the documentation about array_merge say:
If the input arrays have the same string keys, then the later value
for that key will overwrite the previous one.
So you either get the value of the current item or a default value that you can specify in the $columns array.

$array1=Array
(
"companyid" => 1,
"employeeid" => 4,
"role" => "Something",
"name" => "Something",
);
$array2=Array
(
"companyid" => array(2,2,2),
"employeeid" => 5,
"role" => "Something2",
"name" => "Something2"
);
$array3=Array
(
"companyid" => 3,
"employeeid" => 6,
"role" => "Something3",
"name" => "Something3"
);
//Using array_merge
$main_array["companyid"]=array_merge((array)$array1["companyid"],(array)$array2["companyid"],(array)$array3["companyid"]);
$main_array["employeeid"]=array_merge((array)$array1["employeeid"],(array)$array2["employeeid"],(array)$array3["employeeid"]);
for($i=0;$i<count($main_array["companyid"]);$i++)
echo $main_array["companyid"][$i] + "<br />";
for($i=0;$i<count($main_array["employeeid"]);$i++)
echo $main_array["employeeid"][$i] + "<br />";
I've tested the code above and seems right.
You coult also improve this code into a DRY function.

Related

How to remove duplicate arrays from a multi dimensional array?

I have a large multidimensional array that looks like the below.
I want to remove duplicate arrays based on the ID, however, I am struggling to achieve this.
I want the duplicates to work over the entire array, so you can see that ID 1229873 is a duplicate, in the array 2021-07-07 and 2021-07-09, it should therefore be removed from 2021-07-09
How would I achieve this? array_unique has not worked for me.
$data = array (
'2021-07-07' =>
array (
0 =>
array (
'id' => 5435435,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
1 =>
array (
'id' => 1229873,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
),
'2021-07-09' =>
array (
0 =>
array (
'id' => 3243234,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
1 =>
array (
'id' => 1229873,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
),
);
This is a perfect case for array_uunique()! No wait, scratch that. The PHP devs refused to implement it for the perfectly valid reason of... [shuffles notes] "the function name looks like a typo".
[sets notes on fire]
Anyhow, you just need to iterate over that data, keep track of the IDs you've seen, and remove entries that you've already seen.
$seen = [];
foreach(array_keys($data) as $i) {
foreach(array_keys($data[$i]) as $j) {
$id = $data[$i][$j]['id'];
if( in_array($id, $seen) ) {
unset($data[$i][$j]);
} else {
$seen[] = $id;
}
}
}
I've opted for the foreach(array_keys(...) as $x) approach as avoiding PHP references is always the sane choice.
Run it.
I am Sure That is the way which you want to get the unique array.
$unique = array_map("unserialize", array_unique(array_map("serialize", $data)));
echo "<pre>";
print_r($unique);
echo "</pre>";

Codeigniter- How to insert different sizes of arrays into database

I want to insert data in table 'projects'. I have two arrays with different sizes, they are
$advisor_id = array(
'id' =>1
'id' =>2
'id' =>3
);
$project_id = array(
'pid'=>1
'pid'=>2
'pid'=>3
'pid'=>4
);
My code is:
$advisors = count($this->input->post('advisor_id[]'));
$PM_ids = count($this->input->post('PM_id[]'));
if($advisors > $PM_ids){
$count = $advisors;
}else{
$count = $PM_ids;
}
$data[] = array();
for($i =0; $i<$count ; $i++){
$data = array(
'advisor_id' =>$this->input->post('advisor_id')[$i],
'PM_id' =>$this->input->post('PM_id')[$i],
);
//print_r($data);
$this->db->insert_batch('project_config',$data);
}
My problem is the different sizes of arrays. How can I insert into database.
If you are happy to submit NULL values where missing, array_map() is the best tool for the job.
First a general demonstration of how/where NULL elements are generated when array size mismatches occur...
Code: (Demo)
$advisor_id=['id1'=>1,'id2'=>2,'id3'=>3];
$project_id=['pid1'=>1,'pid2'=>2,'pid3'=>3,'pid4'=>4];
$data=array_map(function($id,$pid){return ['advisor_id'=>$id,'PM_id'=>$pid];},$advisor_id,$project_id);
var_export($data); // see how NULL elements are formed in the output array
Output:
array (
0 =>
array (
'advisor_id' => 1,
'PM_id' => 1,
),
1 =>
array (
'advisor_id' => 2,
'PM_id' => 2,
),
2 =>
array (
'advisor_id' => 3,
'PM_id' => 3,
),
3 =>
array (
'advisor_id' => NULL,
'PM_id' => 4,
),
)
The above multi-dimensional array is now fully prepared for a single insert_batch() call. IMPORTANT CodeIgniter's insert_batch() is specifically designed to INSERT multiple rows of data at once -- to use this call inside of a loop defeats the purpose of making this call.
As for you actual implementation, this should work (I don't code in CodeIgniter):
$data=array_map(function($id,$pid){return ['advisor_id'=>$id,'PM_id'=>$pid];},$this->input->post('advisor_id'),$this->input->post('PM_id'));
$this->db->insert_batch('project_config',$data);
CLEAN & DONE: No for loops, no $i counters, and just one call to the database.

Simple PHP array for storing text?

I'm trying to learn some basic PHP but am running into some confusion around using arrays.
I have three "pools" of words. 20 words in each pool for a total of 60 words.
I need to store these in separate arrays, and then pull out a random selection from the array on click of a button. So each time the button is clicked, another four will be pulled from my array of 20 entries.
You can see my non-functioning page here: http://francesca-designed.me/create-a-status/
So the words on the side, when you click the button it'd run through the 20 words in the array and output them in each span, just four each time you click the button.
I looked on the PHP site and found this but I'm confused about which one to use.
Ultimately I would like to add this to a database as in the end if will be 50 words per pool, but for now I want to keep it all in one place while I practice.
<?php
$fruits = array (
"fruits" => array("a" => "orange", "b" => "banana", "c" => "apple"),
"numbers" => array(1, 2, 3, 4, 5, 6),
"holes" => array("first", 5 => "second", "third")
);
?>
There are two types of arrays:
array(
'key' => 'value',
'key' => 'value',
'key' => 'value',
)
and
array(
'value',
'value',
'value',
'value',
);
the latter is the same as:
array(
0 => 'value',
1 => 'value',
2 => 'value',
3 => 'value',
);
it's really how you want to use them...
if you loop through them with
foreach($array as $value) {
}
or
foreach($array as $key => $value) {
}
and there is no need for named keys, just use the second array.
edit:
$array = array(
'one' => array ('qwe1rty1','qwe1rty2','qwe1rty3'),
'two' => array ('qwe2rty1','qwe2rty2','qwe2rty3'),
'three' => array ('qwe3rty1','qwe3rty2','qwe3ert3'),
);
$array['one'][2] === 'qwe1rty3' (index starts at 0)
$array['three'][0] === 'qwe3rty1'
foreach($array['one'] as $key => $value) {
echo $key .' : ' $value;
}
gives
0 : qwe1rty1
1 : qwe1rty2
2 : qwe1rty3
Here is an example that is similar to what you're describing:
$words = array("tasty", "wretched", "simple", "gnarly", "fruitful", "cleeeever");
echo $words[1]; //prints wretched
for($i=0;$i<4;$i++) {//prints array in original order
echo $words[$i].'<br/>';
}
shuffle($words);
for($i=0;$i<4;$i++) {//prints shuffled array
echo $words[$i].'<br/>';
}

PHP array_merge key order

Does it matter in what order the keys in an array array doing an array_merge, i.e. would the keys in the second array below override the keys in the first array:
array1 = array('username' => 'abc', 'level' => 'admin', 'status' => 'active');
array2 = array('level' => 'root', 'status' => 'active', 'username' => 'bcd');
? Or would the order of the keys have to be the same in the two arrays?
The manual states the answer to this question:
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns
the resulting array.
If the input arrays have the same string keys, then the later value
for that key will overwrite the previous one. If, however, the arrays
contain numeric keys, the later value will not overwrite the original
value, but will be appended.
So, yes the keys in the second array will overwrite the keys from the first one if the second array contains some of the same keys.
$array1 = array('username' => 'abc', 'level' => 'admin', 'status' => 'active');
$array2 = array('level' => 'root', 'status' => 'active', 'username' => 'bcd');
$new = array_merge($array1, $array2);
print_r($new);
Output:
Array
(
[username] => bcd
[level] => root
[status] => active
)
So you can see that the keys from the second array overwrote the same keys from first one; the order of the keys in each array does not matter.
Here is an alternative solution that allows the use of a template array to define the output order. Missing fields are filled with null or as specified. In this example the first and last fields are filled with ---.
Please take note of the highlighted text from the previous answer about numeric keys.
function array_merge_template($array1, $array2, $template, $fill=null) {
$_template = array_fill_keys($template, $fill);
return array_intersect_key ( array_replace ( $_template, array_merge($array1, $array2)) , $_template);
}
Input:
$array1 = ['username' =>'abc', 'level' =>'admin', 'status' =>'active', 'foo'=>'x'];
$array2 = ['level' =>'root', 'status' =>'active', 'username' =>'bcd', 'bar'=>'y'];
$template = ['first','level','foo','username','bar','status','last'];
Output:
/* array_merge($array1,$array2) */
[
"username" => "bcd",
"level" => "root",
"status" => "active",
"foo" => "x",
"bar" => "y"
]
/* array_merge_template($array1,$array2,$template,'---') */
[
"first" => "---",
"level" => "root",
"foo" => "x",
"username" => "bcd",
"bar" => "y",
"status" => "active",
"last" => "---"
]

Retrieve first key in multi-dimensional array using PHP

I would like to retrieve the first key from this multi-dimensional array.
Array
(
[User] => Array
(
[id] => 2
[firstname] => first
[lastname] => last
[phone] => 123-1456
[email] =>
[website] =>
[group_id] => 1
[company_id] => 1
)
)
This array is stored in $this->data.
Right now I am using key($this->data) which retrieves 'User' as it should but this doesn't feel like the correct way to reach the result.
Are there any other ways to retrieve this result?
Thanks
There are other ways of doing it but nothing as quick and as short as using key(). Every other usage is for getting all keys. For example, all of these will return the first key in an array:
$keys=array_keys($this->data);
echo $keys[0]; //prints first key
foreach ($this->data as $key => $value)
{
echo $key;
break;
}
As you can see both are sloppy.
If you want a oneliner, but you want to protect yourself from accidentally getting the wrong key if the iterator is not on the first element, try this:
reset($this->data);
reset():
reset() rewinds array 's internal
pointer to the first element and
returns the value of the first array
element.
But what you're doing looks fine to me. There is a function that does exactly what you want in one line; what else could you want?
Use this (PHP 5.5+):
echo reset(array_column($this->data, 'id'));
I had a similar problem to solve and was pleased to find this post. However, the solutions provided only works for 2 levels and do not work for a multi-dimensional array with any number of levels. I needed a solution that could work for an array with any dimension and could find the first keys of each level.
After a bit of work I found a solution that may be useful to someone else and therefore I included my solution as part of this post.
Here is a sample start array:
$myArray = array(
'referrer' => array(
'week' => array(
'201901' => array(
'Internal' => array(
'page' => array(
'number' => 201,
'visits' => 5
)
),
'External' => array(
'page' => array(
'number' => 121,
'visits' => 1
)
),
),
'201902' => array(
'Social' => array(
'page' => array(
'number' => 921,
'visits' => 100
)
),
'External' => array(
'page' => array(
'number' => 88,
'visits' => 4
)
),
)
)
)
);
As this function needs to display all the fist keys whatever the dimension of the array, this suggested a recursive function and my function looks like this:
function getFirstKeys($arr){
$keys = '';
reset($arr);
$key = key($arr);
$arr1 = $arr[$key];
if (is_array($arr1)){
$keys .= $key . '|'. getFirstKeys($arr1);
} else {
$keys = $key;
}
return $keys;
}
When the function is called using the code:
$xx = getFirstKeys($myArray);
echo '<h4>Get First Keys</h4>';
echo '<li>The keys are: '.$xx.'</li>';
the output is:
Get First Keys
The keys are: referrer|week|201901|Internal|page|number
I hope this saves someone a bit of time should they encounter a similar problem.

Categories