Ok, im having troubles figuring out why my str_split is giving strange array output, this is the code:
$test = array(0 => array(53, 22, 12, "string"),
1 => array(94, 84, 94, "string1"),
2 => array(56, 45, 104, "string2"),
3 => array(33, 21, 20, 23, "string3"),
4 => array(44, 55, 66, 77)
);
$newArray = array();
$keys = array_keys($test);
for($i=0; $i < count($test); $i++){
foreach($test[$keys[$i]] as $key => $value){
}
$output = str_split($key);
echo "<pre>";
print_r($output);
echo "</pre>";
Array output is:
Array
(
[0] => 3
)
Array
(
[0] => 3
)
Array
(
[0] => 3
)
Array
(
[0] => 4
)
Array
(
[0] => 3
)
And im expecting output like this:
Array ([0] => 3
[1] => 3
[2] => 3
[3] => 4
[4] => 3
)
Im wondering why is this happening? Thank you.
To achieve the output given, you would just do:
<?php
$test = array(0 => array(53, 22, 12, "string"),
1 => array(94, 84, 94, "string1"),
2 => array(56, 45, 104, "string2"),
3 => array(33, 21, 20, 23, "string3"),
4 => array(44, 55, 66, 77)
);
foreach ($test as $row) {
$output[] = count($row)-1; // non-associative, so the last key is
} // just the length of the array minus 1
print_r($output);
?>
as the sub-arrays are not associative.
If they are, replace the line inside the loop with:
$keys = array_keys($row); // get the keys of the row
$output[] = $keys[count($keys)-1]; // and access the last of them
with your code the solution is, but it is not an efficient way of doing it.
<?php
$test = array(0 => array(53, 22, 12, "string"),
1 => array(94, 84, 94, "string1"),
2 => array(56, 45, 104, "string2"),
3 => array(33, 21, 20, 23, "string3"),
4 => array(44, 55, 66, 77)
);
$newArray = array();
$keys = array_keys($test);
for($i=0; $i < count($test); $i++){
foreach($test[$i] as $key => $value){
$output[$i] = str_split($key)[0];
}
echo "<pre>";
//print_r($output);
echo "</pre>";
}
var_dump($output);
output
array (size=5)
0 => string '3' (length=1)
1 => string '3' (length=1)
2 => string '3' (length=1)
3 => string '4' (length=1)
4 => string '3' (length=1)
But by changing it to this will work, for arrays when the string position is not constant .
<?php
$test = array(0 => array(53, 22, 12, "string"),
1 => array(94, 84, 94, "string1"),
2 => array(56, 45, 104, "string2"),
3 => array(33, 21, "string3", 20, 23),
4 => array(44, 55, 66, 77)
);
$newArray = array();
$keys = array_keys($test);
for($i=0; $i < count($test); $i++){
foreach($test[$i] as $key => $value){
if(is_string($value)){
unset($test[$i][$key]);
}
$output[$i] = count($test[$i]);
}
echo "<pre>";
//print_r($output);
echo "</pre>";
}
var_dump($output);
output
array (size=5)
0 => int 3
1 => int 3
2 => int 3
3 => int 4
4 => int 4
Related
I found a case where I had to add values based on the same week.
[{"week":"30","nilai":"230"},{"week":"30","nilai":"66"},{"week":"29","nilai":"72"},{"week":"29","nilai":"225"},{"week":"28","nilai":"213"},{"week":"28","nilai":"72"},{"week":"27","nilai":"191"},{"week":"27","nilai":"60"},{"week":"26","nilai":"176"},{"week":"26","nilai":"65"},{"week":"25","nilai":"167"},{"week":"25","nilai":"57"},{"week":"24","nilai":"209"},{"week":"24","nilai":"62"},{"week":"23","nilai":"180"},{"week":"23","nilai":"88"},{"week":"22","nilai":"178"},{"week":"22","nilai":"72"},{"week":"21","nilai":"164"},{"week":"21","nilai":"42"},{"week":"20","nilai":"193"},{"week":"20","nilai":"50"},{"week":"19","nilai":"186"},{"week":"19","nilai":"56"}]
the results I expect among others are like this
week => 30,
nilai=> 296
<?php
$input = '[{"week":"30","nilai":"230"},{"week":"30","nilai":"66"},{"week":"29","nilai":"72"},{"week":"29","nilai":"225"},{"week":"28","nilai":"213"},{"week":"28","nilai":"72"},{"week":"27","nilai":"191"},{"week":"27","nilai":"60"},{"week":"26","nilai":"176"},{"week":"26","nilai":"65"},{"week":"25","nilai":"167"},{"week":"25","nilai":"57"},{"week":"24","nilai":"209"},{"week":"24","nilai":"62"},{"week":"23","nilai":"180"},{"week":"23","nilai":"88"},{"week":"22","nilai":"178"},{"week":"22","nilai":"72"},{"week":"21","nilai":"164"},{"week":"21","nilai":"42"},{"week":"20","nilai":"193"},{"week":"20","nilai":"50"},{"week":"19","nilai":"186"},{"week":"19","nilai":"56"}]';
$input = json_decode($input, true);
$outArr = [];
foreach ($input as $arr) {
$week = $arr['week'];
if (key_exists($week, $outArr)) {
$outArr[$week] += $arr['nilai'];
} else {
$outArr[$week] = $arr['nilai'];
}
}
//optional sort - you may remove it
ksort($outArr);
$outArr2 = [];
foreach($outArr as $week => $nilai) {
$outArr2[] = ['week' => $week, 'nilai' => $nilai];
}
var_export($outArr2);
gives result:
array (
0 =>
array (
'week' => 19,
'nilai' => 242,
),
1 =>
array (
'week' => 20,
'nilai' => 243,
),
2 =>
array (
'week' => 21,
'nilai' => 206,
),
3 =>
array (
'week' => 22,
'nilai' => 250,
),
4 =>
array (
'week' => 23,
'nilai' => 268,
),
5 =>
array (
'week' => 24,
'nilai' => 271,
),
6 =>
array (
'week' => 25,
'nilai' => 224,
),
7 =>
array (
'week' => 26,
'nilai' => 241,
),
8 =>
array (
'week' => 27,
'nilai' => 251,
),
9 =>
array (
'week' => 28,
'nilai' => 285,
),
10 =>
array (
'week' => 29,
'nilai' => 297,
),
11 =>
array (
'week' => 30,
'nilai' => 296,
),
)
<?php
$input = '[{"week":"30","nilai":"230"},{"week":"30","nilai":"66"},{"week":"29","nilai":"72"},{"week":"29","nilai":"225"},{"week":"28","nilai":"213"},{"week":"28","nilai":"72"},{"week":"27","nilai":"191"},{"week":"27","nilai":"60"},{"week":"26","nilai":"176"},{"week":"26","nilai":"65"},{"week":"25","nilai":"167"},{"week":"25","nilai":"57"},{"week":"24","nilai":"209"},{"week":"24","nilai":"62"},{"week":"23","nilai":"180"},{"week":"23","nilai":"88"},{"week":"22","nilai":"178"},{"week":"22","nilai":"72"},{"week":"21","nilai":"164"},{"week":"21","nilai":"42"},{"week":"20","nilai":"193"},{"week":"20","nilai":"50"},{"week":"19","nilai":"186"},{"week":"19","nilai":"56"}]';
$input = json_decode($input, true);
$outArr = [];
foreach ($input as $arr) {
$week = $arr['week'];
if (key_exists($week, $outArr)) {
$outArr[$week]['week'] += $arr['nilai'];
} else {
$outArr[$week]['nilai'] = $arr['nilai'];
}
}
print_r($outArr);
?>
You can do that in a single loop using array_reduce.
This solution performs a true single pass without performing any additional searches in the array. I haven't benchmarked it, but I assume it is more performant.
<?php
$values = json_decode('[{"week":"30","nilai":"230"},{"week":"30","nilai":"66"},{"week":"29","nilai":"72"},{"week":"29","nilai":"225"},{"week":"28","nilai":"213"},{"week":"28","nilai":"72"},{"week":"27","nilai":"191"},{"week":"27","nilai":"60"},{"week":"26","nilai":"176"},{"week":"26","nilai":"65"},{"week":"25","nilai":"167"},{"week":"25","nilai":"57"},{"week":"24","nilai":"209"},{"week":"24","nilai":"62"},{"week":"23","nilai":"180"},{"week":"23","nilai":"88"},{"week":"22","nilai":"178"},{"week":"22","nilai":"72"},{"week":"21","nilai":"164"},{"week":"21","nilai":"42"},{"week":"20","nilai":"193"},{"week":"20","nilai":"50"},{"week":"19","nilai":"186"},{"week":"19","nilai":"56"}]');
print_r($values);
$result = array_reduce($values, function ($carry, $item) {
$carry[$item->week] = (object) [
'week' => $item->week,
'nilai' => ($carry[$item->week]->nilai ?? 0) + $item->nilai,
];
return $carry;
}, []);
print "RESULT ... \n";
print_r($result);
Running on Repl.it at https://repl.it/repls/NauticalDamagedBytecode
This solution gives you an array that is keyed by the week number so that you can directly access them without further looping inside the array to retrieve them.
If you do not want that and if you want the array to me indexed like 0, 1, 2, 3, ... them do $result = array_values(array_reduce( ... )) or $result = array_values($result)
I have an array that contains a sub-array. I want to sum the values where the key is the same and to make it in one list.
Here is my array:
$array = array( array(x1=> 1, x2 => 3, y5 => 9),
array(x1=> 3, x4 => 1, y5 => 1),
array(x1=> 1, x8 => 5, a5 => 2),
array(x1=> 2, x10 => 3)
);
And I want to have an array like :
$newarray = array(x1=>7 , x2 => 3, x4=>1, x8=>5, x10=> 3, y5=>9, y5=>1, a5=>2));
some try:
foreach($array as $key => $values)
{
foreach($values as $n_k => $n_v)
{
$newarray [$n_k] += $n_v;
}
}
The problem is you are adding a value even if it is not defined.
You can check if not set by and init the value to 0
if ( !isset($newarray[$n_k]) ) $newarray[$n_k] = 0;
Here is the complete code:
$array = array( array('x1'=> 1, 'x2' => 3, 'y5' => 9), array('x1'=> 3, 'x4' => 1, 'y5' => 1), array('x1'=> 1, 'x8' => 5, 'a5' => 2), array('x1'=> 2, 'x10' => 3, 'b5' => 5));
$newarray = array();
foreach($array as $key => $values){
foreach($values as $n_k => $n_v) {
if ( !isset($newarray[$n_k]) ) $newarray[$n_k] = 0;
$newarray[$n_k] += $n_v;
}
}
This will result to:
Array
(
[x1] => 7
[x2] => 3
[y5] => 10
[x4] => 1
[x8] => 5
[a5] => 2
[x10] => 3
[b5] => 5
)
You can first get all the keys from the array and use that in a array_column and array_sum to get your desired output.
This will probably have more benefit if the array is larger.
$array = array( array("x1" => 1, "x2" => 3, "y5" => 9),
array("x1" => 3, "x4" => 1, "y5" => 1),
array("x1" => 1, "x8" => 5, "a5" => 2),
array("x1" => 2, "x10" => 3, "b5" => 5)
);
$keys = [];
// get all keys used in $array
foreach($array as $subarr){
$keys = array_merge($keys, array_keys($subarr));
}
// $keys is now:
// array (0 => 'x1', 1 => 'x2', 2 => 'y5', 3 => 'x1', 4 => 'x4', 5 => 'y5', 6 => 'x1', 7 => 'x8', 8 => 'a5', 9 => 'x1', 10 => 'x10', 11 => 'b5')
// loop only unique keys and sum the values
foreach(array_unique($keys) as $item){
$res[$item] = array_sum(array_column($array, $item));
}
var_dump($res);
https://3v4l.org/WaqlG
That's not my question, but i've found this that can help you:
https://stackoverflow.com/a/14196064/9721446
You have to create a new array, and then for each equal keyid, you're going to add the value. Somethinkg like that i think it works.
if doesn't help you, take a look at this post, that's not mine too!!!!
Associative array, sum values of the same key
<?php
$input = array( array(x1=> 1, x2 => 3, y5 => 9),
array(x1=> 3, x4 => 1, y5 => 1),
array(x1=> 1, x8 => 5, a5 => 2),
array(x1=> 2, x10 => 3)
);
$final = array();
array_walk_recursive($input, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
print_r($final);
?>
This question already has answers here:
How to Sum Columns of a Multi-Dimensional Array?
(4 answers)
Closed 5 months ago.
I have an arrays with dynamic name. My array could be more than 3, depends and array variable should be unique
$loopThrice = 3;
$getSum = 0;
$total = array();
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
for($a=0; $a < $loopThrice; $a++){ // loop 3x to get unique array name
foreach (${'array'.$a} as $key => $value) { // $array0, $array1, $array2,
//Right here is my problem, I'm not sure if this the correct way to get the sum of $array0,1,2
//get the sum of array0,1,2 -- newarray(8, 18, 26, 34, 42, 50)
$getSum +=
//store newarray
array_push($total, $getSum);
}
}
I need to get an output like this:
Array (
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 43
[5] => 50
)
Why aren't you using a multidimensional array?
$array = array(); // hungarian notation
$array[] = array(5, 10, 15, 20, 25, 30);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10, 12, 14);
In this case you will have an array of arrays:
Array
(
[0] => Array
(
[0] => 5
[1] => 10
[2] => 15
[3] => 20
[4] => 25
[5] => 30
)
[1] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
[2] => Array
(
[0] => 2
[1] => 6
[2] => 8
[3] => 10
[4] => 12
[5] => 14
)
)
You can go with nested for loops:
$sumArray = array();
$arrayCount = count($array);
$elementCount = 0;
foreach($array as $subarray)
{
$count = count($subarray);
$elementCount = $elementCount < $count ? $count : $elementCount;
}
for($i = 0; $i < $elementCount; $i++)
{
$sumArray[$i] = 0;
for($j = 0; $j < $arrayCount; $j++)
{
$sumArray[$i] += $array[$j][$i];
}
}
print_r($sumArray);
The output is
Array
(
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 42
[5] => 50
)
Now, if you have a disproportioned sub-arrays (i.e. different count of elements in each sub-array), you will still get some sort of result, as missing elements will be assumed to be 0. So, with the input of:
$array = array(); // hungarian notation
$array[] = array(5, 10, 15, 20, 25);
$array[] = array(1, 2, 3, 4, 5, 6);
$array[] = array(2, 6, 8, 10);
You will still get the result:
Array
(
[0] => 8
[1] => 18
[2] => 26
[3] => 34
[4] => 30
[5] => 6
)
Well the multi array is the way to go, but you can still do it this way:
$loopThrice = 3;
$getSum = 0;
$total = array();
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
// find which arrray has the most values
for($a=0; $a < $loopThrice; $a++){
$max_index = (count(${'array'.$a}) > $max_index ? count(${'array'.$a}) : $max_index);
}
for($i=0; $i < $max_index; $i++){
for($a=0; $a < $loopThrice; $a++){
$total[$i] += ${'array'.$a}[$i];
}
}
print_r($total);
// prints Array ( [0] => 8 [1] => 18 [2] => 26 [3] => 34 [4] => 42 [5] => 50 )
This should work for you:
$array0 = array(5, 10, 15, 20, 25, 30);
$array1 = array(1, 2, 3, 4, 5, 6);
$array2 = array(2, 6, 8, 10, 12, 14);
$var_prefix = 'array';
$arr_count = 0;
$max_fields = 0;
while(isset(${$var_prefix.$arr_count})) {
$data[] = ${$var_prefix.$arr_count};
if(count(${$var_prefix.$arr_count})>$max_fields) {
$max_fields = count(${$var_prefix.$arr_count});
};
$arr_count++;
}
for($i=0; $i<$max_fields; $i++) {
$result[$i] = array_sum(array_column($data, $i));
}
echo '<pre>';
print_r($result);
echo '</pre>';
die();
I don't know why you have individual array variables, but the process remains the same as if you declare a single array containing those arrays as rows in a multi-dimensional array.
Once you have a multi-dimensional array, the spread operator (...) will feed columns of data into array_map()'s custom function body -- where array_sum() can be called upon.
This task is effectively summing transposed data.
Code: (Demo)
var_export(
array_map(fn() => array_sum(func_get_args()), $array0, $array1, $array2)
);
Or:
var_export(
array_map(fn(...$cols) => array_sum($cols), $array0, $array1, $array2)
);
Output (from either approach):
array (
0 => 8,
1 => 18,
2 => 26,
3 => 34,
4 => 42,
5 => 50,
)
I want get the keys of continuous values of an array.
For example:
how to change this array:
array(
2 => 11,
3 => 11,
4 => 11,
6 => 12,
7 => 13,
8 => 13,
10 => 11,
11 => 11,
12 => 14
)
to this one:
array(
array(2, 3, 4),
array(6),
array(7, 8),
array(10, 11),
array(12)
)
Thx in advance!
Edited Code.
<?php
$arr = [2 => 11, 3 => 11,4 => 11, 6 => 12, 7 => 13, 8 => 13, 10 => 11, 11 => 11,12 => 14];
$newArr = [];
$lastVal = null;
$currArr = [];
foreach($arr AS $key=>$value){
if($lastVal == $value){
$curArr[] = $key;
}else{
if($lastVal != null){
$newArr[] = $curArr;
}
$lastVal = $value;
$curArr = [$key];
}
}
$newArr[] = $curArr;
I'm sure there's a more elegant way.
$data = array(
2 => 11,
3 => 11,
4 => 11,
6 => 12,
7 => 13,
8 => 13,
10 => 11,
11 => 11,
12 => 14
);
$result = array();
array_walk(
$data,
function ($value, $key) use (&$result){
static $v;
if ($value == $v) {
$result[max(array_keys($result))][] = $key;
} else {
$result[] = array($key);
}
$v = $value;
}
);
var_dump($result);
I'm looking for sort an array WITHOUT foreach loop (direct command)...
for example :
<?php
$sortme = array( 10, 8, 17, 6, 22, 4, 3, 87, 1);
asort($sortme);
echo $sortme[0]; //Why this is not the lowest value (which is 1 on this case) ?!
//Is there any direct command sort array WITHOUT foreach loop ?
// iow...
// I need this :
// $sortme = array( 10, 8, 17, 6, 22, 4, 3, 87, 1);
// (here is the magic command) to become this :
// $sortme = array( 1, 3, 4, 6, 8, 10, 17, 22, 87);
?>
Thanks !
sounds like you just need sort()
<?php
$sortme = array( 10, 8, 17, 6, 22, 4, 3, 87, 1);
sort($sortme);
echo '<pre>';
print_r($sortme);
echo '</pre>';
echo 'First: '.$sortme[0];
?>
Result :
Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 6
[4] => 8
[5] => 10
[6] => 17
[7] => 22
[8] => 87
)
First: 1
Here's one way you could do this:
<?php
$fruits = array("3" => "lemon", "4" => "orange", "2" => "banana", "1" => "apple");
asort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
Should give you this output:
1 = apple
2 = banana
3 = lemon
4 = orange