Dynamic array key in while loop - php

I'm trying to get this working:
I have an array that gets "deeper" every loop. I need to add a new array to the deepest "children" key there is.
while($row = mysql_fetch_assoc($res)) {
array_push($json["children"],
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
}
So, in a loop it would be:
array_push($json["children"] ...
array_push($json["children"][0]["children"] ...
array_push($json["children"][0]["children"][0]["children"] ...
... and so on. Any idea on how to get the key-selector dynamic like this?
$selector = "[children][0][children][0][children]";
array_push($json$selector);

$json = array();
$x = $json['children'];
while($row = mysql_fetch_assoc($res)) {
array_push($x,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$x = $x[0]['children'];
}
print_r( $json );

Hmmm - maybe better to assign by reference:
$children =& $json["children"];
while($row = mysql_fetch_assoc($res)) {
array_push($children,
array(
"id" => "$x",
"name" => "Start",
"children" => array()
)
);
$children =& $children[0]['children'];
}

$json = array();
$rows = range('a', 'c');
foreach (array_reverse($rows) as $x) {
$json = array('id' => $x, 'name' => 'start', 'children' => array($json));
}
print_r($json);
If you want to read an array via a string path, split the string in indices, and then you can do something like this to get the value
function f($arr, $indices) {
foreach ($indices as $key) {
if (!isset($arr[$key])) {
return null;
}
$arr = $arr[$key];
}
return $arr;
}

Related

php array: if identical key values then choose highest by other key value

$myArray = [
"ID" => "",
"Module" => "",
"Version"=> ""
];
Output:
[
{23,finance,1.0},
{24,finance,1.1},
{25,logistic,1.0}
]
I have an array with the given Keys like above. I need a new array that gives me the highest Version IF module is same. How would I do that?
desired Output:
[
{24,finance,1.1},
{25,logistic,1.0}
]
This is what I tried
$modulesFiltered = [];
$i = 0;
$j = 0;
foreach($modules as $module){
$modulesFiltered[$i]['ID'] = $module['ID'];
foreach($modulesFiltered as $moduleF){
if(!empty($moduleF[$j]['Module'])){
if($module[$i]['Module'] == $moduleF[$j]['Module']){
$modulesFiltered[$i]['Module'] = 'this is doubled';
}
} else {
$modulesFiltered[$i]['Module'] = $module['Module'];
}
$j++;
}
$modulesFiltered[$i]['Module'] = $module['Module'];
$i++;
}
I tried to debug your code though.The problem is that you try to access element [0] of $moduleF. You should change $moduleF[$j]['Module'] to $moduleF['Module'].
Use standard functions where possible. for finding values within (multidimensional) array's you can use array_search. The code beneath works.
Also don't compare strings with == use strcmp(str1, str2) == 0 instead
$inputArray = array(
array(
"ID" => 23,
"Module" => "finance",
"Version"=> 1.0),
array(
"ID" => 24,
"Module" => "finance",
"Version"=> 1.1),
array(
"ID" => 25,
"Module" => "logistiscs",
"Version"=> 1.0));
$output = array();
foreach($inputArray as $element)
{
$key = array_search($element["Module"], array_column($output, "Module"));
if(is_numeric($key))
$output[$key]["Version"] = max($element["Version"], $output[$key]["Version"]);
else
$output[] = $element;
}
print_r($output);

PHP array within array

Can someone explain to me why this isn't working? I'm trying to push an array into another array, but its only coming back with the last item from the $votes array.
foreach($json['area'] as $row) {
$name = $row['name'];
$group = $row['array']['group'];
$majority = $row['array']['majority'];
$candidates = $row['array']['candidates'];
foreach ($candidates as $candidate) {
$vote = $candidate["votes"];
$candi = $candidate["name"];
$votes = array("vote" => $vote, "candidate" => $candi);
}
$array = array("name" => $name, "group" => $group, "majority" => $majority, "votes" => $votes);
$results[] = $array;
}
Each iteration of the outer loop is only producing a single $votes array , seemingly for a single candidate, in this line:
$votes = array("vote" => $vote, "candidate" => $candi);
If you want to capture multiple entries in that array for each row, you need to make it a multi-dimensional array also:
$candidates = $row['array']['candidates'];
$votes = [];
foreach ($candidates as $candidate) {
$votes[] = array(
"vote" => $candidate["votes"],
"candidate" => $candidate["name"]
);
}
$array = array(
"name" => $name,
"group" => $group,
"majority" => $majority,
"votes" => $votes
);

Create an array with dynamic input in PHP

I have to create a array dynamically like I have a method which will pass keys and based on those keys I need to create arrays inside them
Format will be like-
{
"TEST1":{
"140724":[
{
"A":"1107",
"B":4444,
"C":"1129",
"D":"1129"
},
{
"A":"1010",
"B":2589,
"C":"1040",
"D":"1040"
}
],
"140725":[
]
}
}
So how should I frame this logic inside for loop. I am new to php so formatting the same creating trouble.
$json_Created = array("TEST1" => array());
foreach($val as $key=>$value){
array_push($json_created,array($key = array()));
}
The entire array is dynamic, so like I have 140724 ,,, till 140731 (actually date format yymmdd), any amount if numbers can be considered. SO that part is dynamic moreover some dates may be wont have any values and some will have.
So my main point is to develop that logic so that irrespective the
number of inputs , my array formation must be intact.
You can use json_encode with array to do so
$array = array(
"TEST1" => array(
"140724" => array(
array(
"A" => "1107",
"B" => "4444",
"C" => "1129",
"D" => "1129"
),
array (
"A" => "1010",
"B" => "2589",
"C" => "1040",
"D" => "1040"
)
),
"140725" => array(
)
)
);
echo json_encode($array);
Another way to construct array is
$array = array();
$array["TEST1"]["140724"][] = array(
"A" => "1107",
"B" => "4444",
"C" => "1129",
"D" => "1129"
);
$array["TEST1"]["140724"][] = array (
"A" => "1010",
"B" => "2589",
"C" => "1040",
"D" => "1040"
);
$array["TEST1"]["140725"] = array();
echo json_encode($array);
Finally managed to write the code-
$keys_content = array("starttime", "id", "duration", "endtime");
$dates = array();//140724,140725,140726140727
$mainID =“TEST1”;
$arraySuperMain = array();
$arrayMain = array();
for ($j = 0; $j < count($dates); $j++) {
$array_main = array();
$subset = array();
for ($i = 0; $i < count($keys_content); $i++) {
$key = $keys_content[$i];
$subset = array_push_assoc($subset, $key, "Value".$i);
}
$array_main = array_push_assoc($array_main, $dates[$j], $subset);
array_push($arrayMain, $array_main);
}
$createdJSON = array_push_assoc($arraySuperMain, $mainID, $arrayMain);
public static function array_push_assoc($array, $key, $value) {
$array[$key] = $value;
return $array;
}

Flatten multidimensional array to 3 levels preserving the first level keys

I have a nested multidimensional array like this:
$array = [
1 => [
[
['catName' => 'Villes', 'catUrl' => 'villes', 'parent' => 151],
[
['catName' => 'Administratif', 'catUrl' => 'territoire', 'parent' => 37],
[
['catName' => 'Gegraphie', 'catUrl' => 'geographie', 'parent' => 0]
]
]
]
]
];
I would like to flatten it to a simpler structure, like this:
array (
1 =>
array (
0 =>
array (
'catName' => 'Villes',
'catUrl' => 'villes',
'parent' => 151,
),
1 =>
array (
'catName' => 'Administratif',
'catUrl' => 'territoire',
'parent' => 37,
),
2 =>
array (
'catName' => 'Gegraphie',
'catUrl' => 'geographie',
'parent' => 0,
),
),
)
I suppose it would work with some recursive function, but my skills in there are not my best. How can I accomplish this?
Here is one way to do it. This function will collapse each level:
function collapse($array) {
// End of recursion is indicated when the first element is not an array.
if (!is_array(reset($array))) {
return array($array);
}
// Otherwise, collapse it.
return array_reduce($array, function($carry, $item) {
// Recursively collapse each item and merge them together.
return array_merge($carry, collapse($item));
}, array());
}
It can be applied to your array like this:
$collapsed = array_map("collapse", $array);
It's not pretty, but it works:
$deeparray = array(); // the really nested array goes here
$flattened = array();
function flatten($item,$key)
{
global $flattened;
if ( $key == 'catName' || $key == 'catUrl' || $key == 'parent' )
{
if ( sizeof( $flattened) == 0 )
{ $flattened[] = array( $key=>$item ); }
else
{
$last = array_pop($flattened);
if ( array_key_exists($key,$last) )
{
$flattened[] = $last;
$flattened[] = array( $key=>$item );
}
else
{
$last[ $key ] = $item;
$flattened[] = $last;
}
}
}
}
array_walk_recursive($deeparray,'flatten',$flattened);
$flattened = array($flattened);
Make a recursive call on each first level element.
Within the recursive function, first isolate the non-iterable elements and push them as a single new row into the desired result array. Then execute the recursive function on each iterable element on that level.
It is important to "pass data back up" with each each recursive call so that all deep data can be collected and returned in the top-level/finished array.
The global-level foreach modifies by reference so that the assignment of $parent mutates the original input array.
Code: (Demo)
function flattenRows($array) {
$result = [];
$scalars = array_filter($array, 'is_scalar');
if ($scalars) {
$result[] = $scalars;
}
foreach (array_diff_key($array, $scalars) as $item) {
$result = array_merge($result, flattenRows($item));
}
return $result;
}
$result = [];
foreach ($array as &$parent) {
$parent = flattenRows($parent);
}
var_export($array);
You could try
foreach($toplevel as $a){
$finalarray = $a[0];
}
if the structure will always be the same as what you've shown then i think you can do this:
$newarray[1][0] = $oldarray[1][0][0];
$newarray[1][1] = $oldarray[1][0][1][0];
$newarray[1][2] = $oldarray[1][0][1][1][0];

Sorting PHP array(s) based on their initial keys?

I want to sort my initial array(s) that contain many keys and values inside, into array(s) sorted by a specific key, and all the values for that key in a single array based on the key.
So here's the array I have:
$Before = Array(Array("id" => 1, "name" => "Dogs"),
Array("id" => 2, "name" => "Lions"),
Array("id" => 3, "name" => "Tigers"));
And this is the array that I would like to end up with:
$After = Array("ids" => Array(1, 2, 3),
"names" => Array("Dogs", "Lions", "Tigers"));
I hope that makes sense. I found it easier to show you an example, as oppose to describing it.
$after = array(
'ids' => array(),
'names' => array()
);
foreach($before as $row){
$after['ids'][] = $row['id'];
$after['names'][] = $row['name'];
}
var_dump($after);
You can use array_reduce
$After = array_reduce($Before, function ($a, $b) {
$a['ids'][] = $b['id'];
$a['names'][] = $b['name'];
return $a;
});
Live DEMO
Maybe something like:
foreach ($input as $item) {
foreach ($item as $field => $value) {
$result[$field][] = $value;
}
}
var_dump($result);
$After = array();
foreach ($Before as $a) {
$After['ids'][] = $a['id'];
$After['names'][] = $a['name'];
}
This should work :)

Categories