I try to build an array. I don't wanna write something like $array[3][5][8] = []. Because the count of the first Array can change, here it's 3 but it also can be like 9 or 12. Also the values can change, but they are always unique numbers. I hope someone knows a better way. Thank you.
// First Array, which I have. The count and the content can change.
array(3) {
[0]=>
string(1) "3"
[1]=>
string(1) "5"
[2]=>
string(1) "8"
}
// Second Array, thats the goal.
array(1) {
[3]=>
array(1) {
[5]=>
array(1) {
[8]=>
array(0) {
}
}
}
}
This code will solve your problem:
$array = [3,5,8,9]; // your first array
$newArray = null;
foreach ($array as $value) {
if($newArray === null) {
$newArray[$value] = [];
$ref = &$newArray[$value];
}
else {
$ref[$value] = [];
$ref = &$ref[$value];
}
}
$newArray - holds the result you wanted
$array1=array(3,5,8);
$array2=array();
for($i=count($array1);$i>0;$i--){
$temp=array();
$temp[$array1[$i-1]]=$array2;
$array2=$temp;
}
$subject is the reference to the array you are currently in.
$array is the main root array that you obtain in the end.
$input is the input int array.
$subject = $array = [];
foreach($input as $key){
$subject[$key] = []; // create empty array
$subject =& $subject[$key]; // set reference to child
// Now $subject is the innermost array.
// Editing $subject will change the most nested value in $array
}
Related
Hello I've multidimensional array that looks like that:
array(13890) {
[0]=>
array(2) {
["Icd"]=>
array(2) {
["id"]=>
int(111)
["nazwa"]=>
string(6) "DŻUMA"
}
["ProjectIcd"]=>
array(0) {
}
}
[1]=>
array(2) {
["Icd"]=>
array(2) {
["id"]=>
int(566)
["nazwa"]=>
string(7) "ŚWINKA"
}
["ProjectIcd"]=>
array(0) {
}
}
An so on.
I want to change it so it looks something like that:
array(13890) {
[0]=> array(2) {
["id"]=>
int(111)
["text"]=>
string(6) "DŻUMA"
}
How is this possible to do?
I want to add, I want to convert the array to json and feed it to select2 js in ajax.
Will that be a problem or not?
Short solution using array_map function:
// $arr is your initial array
$new_arr = array_map(function($a){
return ['id' => $a['Icd']['id'], 'text' => $a['Icd']['nazwa']];
}, $arr);
So you can simple create a new array and add there the values, which you want based on the old array. Then you convert the array to a json string with the php function json_encode():
$array = array("text"=>$old_array[0]["Icd"]["nazwa"]);
echo json_encode($array);
I hope this is something that you want.
$res = [];
$i = 0;
foreach($array as $arr) {
//get keys
if (count($arr) > 0) {
$keys = array_keys($arr);
// loop through the keys and fetch data of those keys
// put in array
foreach($keys as $key) {
if ($arr[$key]) {
$res[$i]['id'] = $arr[$key]['id'];
$res[$i]['text'] = $arr[$key]['nazwa'];
}
$i++;
}
}
}
print_r($res);
// To change array to json
echo json_encode($res);
I have a database with multiple records. It is structured like this:
["data"]=>
array(5) {
[1]=>
[2]=>
array(11) {
[0]=>
string(1) "0"
[1]=>
string(8) "25000000"
[2]=>
string(3) "day"
[3]=>
string(5) "0.00%"
[4]=>
string(9) "404049904"
[5]=>
string(1) "0"
[6]=>
string(5) "0.00%"
[7]=>
string(1) "0"
[8]=>
string(1) "0"
[9]=>
string(1) "0"
[10]=>
string(3) "0.0"
}
I need to fetch the 8th record and I do this by using
public static function($data)
{
$array = [];
$path = $data->data[2];
foreach($path as $key => $item)
if($key > 1)
{
$array[] = [$item->data[8]];
}
return json_encode($array);
}
This foreach takes all the 8th values from the array but I need to display a single number which is the average of all the 8th values. How can I do this?
Once you've got your array containing all your data, simple sum the array and then divide by the size of the array.. something along these lines
$average = (array_sum($array) / count($array));
Of course you may want to check for count($array) being 0;
Because you put your value into a new array, you can not use array_sum to sum the values, so you should store it.
$sum = 0;
foreach($path as $key => $item)
if($key > 1) {
$array[] = [$item->data[8]];
$sum += $item->data[8];
}
}
$avg = ($sum / count($array); //the average
var_dump($avg);
If is it possible, just put it as a value:
$array[] = $item->data[8]; //no wrapping []
In this case, you can use $avg = array_sum($array) / count($array);
if (count($array)>0){
$avg = array_sum($array) / count($array);
}
I would personally do those calculations in the database before the data gets to your PHP script itself. See AVG().
If you can't for some reason use that I would output those values into a flat array and then just calculate the average. So something like :
function getAverage($data) {
$flatArray = array();
foreach ($data as $row) {
if (!empty($row->8)) {
$flatArray[] = $row->8;
}
}
return (array_sum($flatArray)/count($flatArray));
}
EDIT: Moved to Object traversing on the data row, sorry, missed that initially and thought it was an array in all the nests.
Since you have a loop within your static Method; why not do the calculation therein and return it or add it to the JSON Data if You need your Data in JSON Format? Here's what's implied by the above:
public static function getAverageSum($data) {
$array = [];
$path = $data->data[2];
$sumTotal = 0.00; //<== YOU COULD JUST SUM IT DIRECTLY WITHOUT USING AN ARRAY
foreach($path as $key => $item) {
if ($key > 1) {
$array[] = $item->data[8];
$sumTotal += floatval($item->data[8]);
}
}
// IF YOU ARE ONLY INTERESTED IN THE AVERAGE SUM YOU COULD EVEN ADD IT IT TO THE $array AS AN EXTRA KEY
// LIKE SO:
$arrLen = count($array);
$array['avgSum'] = $sumTotal/$arrLen;
// IF YOU NEED YOUR DATA IN JSON... THEN RETURN THE JSON ENCODED DATA WITH SUM AS PART OF THE DATA.
// YOU'D HAVE NO NEED FOR array_sum() SINCE YOU DID YOUR PREP-WORK ALREADY...
return json_encode($array);
// ALTERNATIVELY; IF ALL YOU NEED IS JUST THE AVERAGE SUM; YOU COULD AS WELL DIRECTLY RETURN $sumTotal/$arrLen
return ($sumTotal/$arrLen);
}
Really struggling with this. I have a multidimensional array n levels deep. Each 'array level' has information I need to check (category) and also check if it contains any arrays.
I want to return the category ids of all the arrays which have a category and do not contain an array (i.e. the leaves). I can echo output properly, but I am at a loss as how to return the ids in an array (without referencing)
I have tried RecursiveIteratorIterator::LEAVES_ONLY and RecursiveArrayIterator but I don't think they work in my case? (Maybe I am overlooking something)
$array
array(2) {
["1"]=>
string(5) "stuff"
["2"]=>
array(2) {
["category"]=>
string(1) "0"
["1"]=>
array(3) {
[0]=>
array(3) {
["category"]=>
string(1) "1"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["category"]=>
string(1) "2"
["1"]=>
string(5) "stuff"
["2"]=>
string(5) "stuff"
}
[1]=>
array(5) {
["1"]=>
string(5) "stuff"
["32"]=>
string(5) "stuff"
}
}
}
}
My function
public function recurs($array, $cats = [])
{
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$this->recurs($value, $cats);
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return $array_cat;
}
}
Calling it
$cats_array = $this->recurse($array)
Output echoed
echoing the category here works fine: 1
echoing the category here works fine: 2
How do I return the ids in an array to use in the $cats_array variable?
EDIT: The output should match the echo, so I should get an array containing (1, 2) since they are the only arrays with categories and no arrays within them
array(2){
[0]=>
int(1) "1"
[1]=>
int(1) "2"
}
If I understood you correctly this function will do the job:
function getCategories(array $data)
{
if ($subArrays = array_filter($data, 'is_array')) {
return array_reduce(array_map('getCategories', $subArrays), 'array_merge', array());
};
return array_key_exists('category', $data) ? array($data['category']) : array();
}
If the array contains any sub-arrays they will be returned by array_filter and you will enter the if statement. array_map will apply the function recursively to the sub-arrays and array_reduce will merge the results.
If the array doesn't contain any sub-arrays you will not enter the if statement and the function will return an array with the category if it is present.
Note that you might need to use array_unique to return unique categories.
Also for small performance optimization instead of array_key_exists you can use isset($array[$key]) || array_key_exists($key, $array).
Update
If you want to update your function to make it work you have to recursively collect and merge the sub results. In the following example I introduced a new variable for this:
public function recurs($array, $cats = [])
{
$result = [];
$array_cat = '';
$has_array = false;
// Check if an id exists in the array
if (array_key_exists('category', $array)) {
$array_cat = $array['category'];
}
// Check if an array exists within the array
foreach ($array as $key => $value) {
if (is_array($value)) {
$has_array = true;
$result = array_merge($result, $this->recurs($value, $cats));
}
}
// If a leaf array
if (!$has_array && is_numeric($array_cat)) {
echo "echoing the category here works fine: " . $array_cat . "\n";
return [$array_cat];
}
return $result;
}
this is my array:
$array= array(3) {
[0]=> array(3) { ["name"]=> "one" ["com"]=> "com1" ["id"]=> "1" }
[1]=> array(3) { ["name"]=> "two" ["com"]=> "com2" ["id"]=> "2" }
[2]=> array(3) { ["name"]=> "three" ["com"]=> "com3" ["id"]=> "3" }
I need posibility to change values of name and com for specific id. I try some examples from Stack questions:
1.Link1
foreach($array as &$value){
if($value['id'] == 1){
$value['name'] = 'test';
$value['com'] = 'test';
break; // Stop the loop after we've found the item
}
}
But it don't work. no error but no result too.
2.Link 2
Again,no error message,but no result...
I also try a lot of other examples from Stack but fake,and finaly to write a question..
Buy,
P
Since you are not changing your array value that's why it's-not giving you desired output. Try this:-
foreach($array as $key => &$value){
if($key == 1){
$array[1]['name'] = 'test';// change value to original array
$array[1]['com'] = 'test'; //change value to original array
break; // Stop the loop after we've found the item
}
}
for($i=0;$i<count($array);$i++) {
if($array[$i]['id'] == 1) {
$array[$i]['name'] = 'test';
$array[$i]['com'] = '';
break;
}
}
print_r($array);
If you are able to change the array on creation I would recommend shifting the id to the array's key identifier. Would make life a lot easier to just do:
$array[1]['name'] = 'test';
Otherwise use the for loop posted above and look it up. (Right awnser)
I have an array that groups different items by item type. I am grouping the result by category_id field. What I want is the output to be
item1 = 3
item2 = 2
My array looks like this if I do a var_dump()
array(2) {
["item1"]=>
array(3) {
[0]=>
string(1) "3"
[2]=>
string(1) "5"
[4]=>
string(1) "7"
}
["item2"]=>
array(2) {
[1]=>
string(1) "4"
[3]=>
string(1) "6"
}
}
Here is the code I am using:
$items = Item::where('order_id','=',$payload["orderId"])->get();
$itemsGrouped = [];
$count = 0;
foreach($items as $item){
$itemsGrouped[$item->category_id][$count] = $item->id;
$count++;
}
foreach($itemsGrouped as $grp){
echo key($itemsGrouped).'='.count($grp).'<br>';
};
And here is what I am currently getting. The count is working but not the $itemsGrouped key. It is duplicated.
item2=3<br>item2=2<br>
Change your code as below
foreach($itemsGrouped as $key => $grp){
echo $key.'='.count($grp).'<br>';
};
In order to use key() function, you need to traverse the array using next/current function
foreach($itemsGrouped as $key => $grp){
echo $key.'='.count($grp).'<br>';
};
key() function returns the current element's key, which is defined by an array's internal pointer. Obviously it always points to the last element.
$myarray = "Your array";
$count = array(); // create an empty array
foreach($myarray as $arr) {
foreach($arr as $a) {
$key = array_keys($a);
$count[$key[0]]++;
}
}
print_r($count);