How to add values into an associative array? - php

If I want to add values to an array in a while loop I could do $arr[] = "some". But how can I do this if I have an associative array, for example:
while($result = $result->fetch_array(MYSQLI_ASSOC))
{
$arr[]["some_key"] = "some";
$arr[]["other_key"] = "some2";
}
But this will give me something like Array ( [0] => Array ( [some_key] => some) [1] => Array ( [other_key] => some2). So what is the right way to add values into an associative array inside a loop?

Create a temporary array for your keys, and then push that temporary array onto the main one:
$arr = [];
loop(condition) {
$tmp = [];
$tmp['some_key'] = 'some value';
$tmp['other_key'] = 'other value';
$arr[] = $tmp;
}

This will not overwrite your values:
$arr = array();
while($result = $result->fetch_array(MYSQLI_ASSOC))
{
$tmp = array();
foreach($result as $key=>$value)
{
$tmp[$key] = $value;
}
$arr[]=$tmp;
}
Or more succinctly:
$arr = array();
while($result = $result->fetch_array(MYSQLI_ASSOC))
{
$arr[]=$result;
}
Since PHP defaults to copying rather than referencing.
If you wanted to store them as an assoc. array of arrays you might do this:
$arr = array();
while($result = $result->fetch_array(MYSQLI_ASSOC))
{
foreach($result as $key=>$value)
{
if(!isset($arr[$key])){
$arr[$key] = array();
}
$arr[$key][] = $value;
}
}

Related

Merging associative array with same values?

I have an associative array -
{
"1":{"list_price_9":"1250.0000","list_price_18":"1250.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"2":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"3":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"4":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"5":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"6":{"list_price_9":"2500.0000","list_price_18":"2500.0000","golflan_price_9":"0.0000","golflan_price_18":"2500.0000"},
"7":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"2500.0000"}
}
I want to convert the array such that the resulting array has merged the keys with similar values in a comma separated string.
So the result will be something like this -
{
"1":{"list_price_9":"1250.0000","list_price_18":"1250.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"2,3,4,5,7":{"list_price_9":"0.0000","list_price_18":"0.0000","golflan_price_9":"0.0000","golflan_price_18":"1250.0000"},
"6":{"list_price_9":"2500.0000","list_price_18":"2500.0000","golflan_price_9":"0.0000","golflan_price_18":"2500.0000"}
}
This seems simple, but I am not being able to come up with an elegant solution for this.
Kindly help.
I tried something like this -
$common_prices = array();
foreach ($pricelist as $day => $prices) {
foreach ($common_prices as $new_day => $new_prices) {
if($prices === $new_prices) {
$modified_day = $new_day.','.$day;
$common_prices[$modified_day] = $new_prices;
unset($new_day);
}
}
$common_prices[$day] = $prices;
}
where $pricelist is the given array and $common_prices is the expected array. But obviously this will not work.
You can do it with linear complexity using intermediate array of accumulated keys for unique values:
$keys = [];
foreach($pricelist as $key=>$val) {
$str = json_encode($val);
if(!isset($keys[$str])) {
$keys[$str] = [];
}
$keys[$str][] = $key;
}
$common_prices = [];
foreach($keys as $key=>$val) {
$common_prices[join(',',$val)] = json_decode($key);
}
You can just aggregate keys and data in the separated arrays and then combine them.
Example:
$keys = [];
$data = [];
foreach ($pricelist as $day => $prices) {
if ($key = array_search($prices, $data))
$keys[$key] .= ',' . $day;
else {
$keys[] = $day;
$data[] = $prices;
}
}
$common_prices = array_combine($keys, $data);

Merging and looping multi dimensional array

I'm trying to loop some array using foreach. This is the code which demonstrates what I'm doing
$q = "SELECT * "
."FROM ".TBL_FRUITSDETAILS."";
$fruitsdetails = $database->query($q);
$var = array();
while($line = mysql_fetch_assoc($fruitsdetails)){
$var[] = $line;
}
$q = "SELECT * "
."FROM ".TBL_NUMDETAILS."";
$numdetails = $database->query($q);
$var2 = array();
while($line2 = mysql_fetch_assoc($numdetails)){
$var2[] = $line2;
// $n++;
}
$out = array();
foreach ($var as $key => $value){
// $out[] = array_merge_recursive($value, $var2[$key]);
foreach ($var2 as $key => $value) {
$out1[] = array_merge_recursive($var[$key], $var2[$key]);
}
}
print_r(json_encode($out1));
However, this outputs
appleone
bananatwo
appleone
bananatwo
and I want to display it like this instead
appleone
appletwo
bananaone
bananatwo
Try this,
$var = array (1,2);
$var2 = array (a,b);
$out = array();
foreach ($var as $key => $value){
foreach($var2 as $k=>$v){
$out[] = $value.$v;
}
}
print_r(json_encode($out));
I think your loop should be something like this. There's no need of using array_merge_recursive function
$var = array (1,2);
$var2 = array ('a','b');
$result = array();
foreach($var as $key => $val){
foreach($var2 as $k => $v){
$result[] = $val.$v;
}
}
There is no need to use array_merge_recursive just a nested loop will suffice:
$var = array (1,2);
$var2 = array ('a','b');
$out = array();
foreach($var as $arrayNumeric){
foreach($var2 as $arrayAlphaNumeric){
$out[] = $arrayNumeric.$arrayAlphaNumeric;
}
}

How to extend a multidimensional array in php

if my code looks like...
$result = $mysqli->query("SELECT id, name, color FROM fruits");
$list = array();
while($r = $result->fetch_array()) {
$list[] = $r;
}
print json_encode(array('list' => $list));
the result is...
list[0].id = '1', list[0].name = 'apple', list[0].color = 'red';
list[1].id = '2', list[1].name = 'banana', list[1].color = 'yellow';
...
It's fine, but i need additional infos in the list.
How can i extend the arrays and get something like:
list[0].id = '1', list[0].name = 'apple', list[0].color = 'red', list[0].taste = 'sour';
list[1].id = '2', list[1].name = 'banana', list[1].color = 'yellow', list[0].taste = 'sweet';
...
This does not work:
$result = $mysqli->query("SELECT id, name, color FROM fruits");
$list = array();
while($r = $result->fetch_array()) {
$list[] = $r;
$list[]['taste'] = 'sweet'; //DOES NOT WORK
array_push($list,array("taste" => 'sweet')); //DOES ALSO NOT WORK
}
print json_encode(array('list' => $list));
Thank you!!!
Because $list[] = $value is the same as array_push($list, $value). There's no such thing as $list[]['key'].
You should add it to the $r variable instead, before you add it to $list:
while($r = $result->fetch_array()) {
$r['taste'] = 'sweet'; //DOES WORK!
$list[] = $r;
}
If you already have $list, you can simply loop through and add it:
foreach ($list as &$array) {
$array['taste'] = 'sweet';
}
unset($array); //remember to unset references
..or if you hate references:
foreach ($list as $key => $array) {
$list[$key]['taste'] = 'sweet';
}
You need an intermediate variable
$result = $mysqli->query("SELECT id, name, color FROM fruits");
$list = array();
while($r = $result->fetch_array()) {
$r['taste'] = 'sweet'; //Modify an existing array
$list[] = $r;
}
print json_encode(array('list' => $list));

php is assigning last result to all array keys

There is some problem, the code below assigning the last pr_name to all keys.
$arr = array();
while($row = mysql_fetch_array($results)) {
$keys[] = $row['pr_code'];
$items = array_fill_keys($keys, $row['pr_name']);
}
Simply with this:
$items = array();
while($row = mysql_fetch_array($results)) {
$items[$row['pr_code']] = $row['pr_name'];
}

How do I invert a multidimensional array in PHP

Whats the easiest way to invert a multidimensional array. By invert I mean similar to array_flip.
e.g
[0][5][var_name] = data
[0][3][var_name2] = data2
[1][var_name3] = data3
[0][1][4][var_name4] = data4
inverted would be:
[var_name][0][5] = data
[var_name2][0][3] = data2
[var_name3][1] = data3
[var_name4][0][1][4] = data4
Any ideas?
You could store a list of the keys of all ancestors and when you hit a "leaf" use this list to create the "flipped" version.
<?php
$data = array(
0=>array(
5=>array('var_name' => 'data'),
3=>array('var_name2' => 'data2'),
1=>array(4=>array('var_name4'=>'data4'))
),
1=>array('var_name3'=>'data3')
);
$result = array();
foo($data, $result);
($result['var_name'][0][5] === 'data') or die('1');
($result['var_name2'][0][3] === 'data2') or die('2');
($result['var_name3'][1] === 'data3') or die('3');
($result['var_name4'][0][1][4] === 'data4') or die('4');
echo 'ok';
function foo(array $a, array &$target, $stack=array()) {
foreach($a as $key=>$value) {
if ( is_array($value) ) {
array_push($stack, $key);
foo($value, $target, $stack);
array_pop($stack);
}
else {
$target[$key] = array();
$tmp = &$target[$key];
foreach( $stack as $s ) { // now it's not so stack-ish anymore :-S
$tmp[$s] = array();
$tmp = &$tmp[$s];
}
$tmp = $value;
}
}
}
I couldn't think of an easy way to do this. So I wrote up a really complicated way to do it. Namely:
Take the multidimensional array and flatten it into a list of keys and values.
Reverse the keys.
Unflatten the list to obtain an inverted multidimensional array.
Code
<?php
function print_entries($array, $prekeys = array())
{
foreach ($array as $key => $value)
{
$keys = array_merge($prekeys, array($key));
if (is_array($value))
print_entries($value, $keys);
else
echo '[' . implode('][', $keys) . "] = $value\n";
}
}
function flatten_array($array)
{
$entries = array();
foreach ($array as $key => $value)
{
if (is_array($value))
{
foreach (flatten_array($value) as $subentry)
{
$subkeys = $subentry[0];
$subvalue = $subentry[1];
$entries[] = array(array_merge(array($key), $subkeys), $subvalue);
}
}
else
$entries[] = array(array($key), $value);
}
return $entries;
}
function unflatten_array($entries)
{
$array = array();
foreach ($entries as $entry)
{
$keys = $entry[0];
$value = $entry[1];
$subarray = &$array;
foreach ($keys as $i => $key)
{
if ($i < count($keys) - 1)
{
if (!isset($subarray[$key]))
$subarray[$key] = array();
$subarray = &$subarray[$key];
}
else
$subarray[$key] = $value;
}
}
return $array;
}
function invert_array($array)
{
$entries = flatten_array($array);
foreach ($entries as &$entry)
$entry[0] = array_reverse($entry[0]);
return unflatten_array($entries);
}
$array = array
(
0 => array
(
5 => array('var_name' => 'data'),
3 => array('var_name2' => 'data2'),
1 => array(4 => array('var_name4' => 'data4'))
),
1 => array(0 => array('var_name' => 'data3'))
);
print_entries($array);
echo "\n";
print_entries(invert_array($array));
?>
Output
[0][5][var_name] = data
[0][3][var_name2] = data2
[0][1][4][var_name4] = data4
[1][0][var_name] = data3
[var_name][5][0] = data
[var_name2][3][0] = data2
[var_name4][4][1][0] = data4
[var_name][0][1] = data3
Edit: I noticed now that you don't reverse the keys but you simply move the var_name portion from the end to the front and leave the numerical indices alone. It's easy enough to modify the line in flatten_array where I call array_reverse to re-order the keys in a different way. The core flatten/unflatten logic would not need to be changed. I leave this as an exercise for the reader. :-)

Categories