I have an array that looks something like this
array(7) {
[0]=> "hello,pat1"
[1]=> "hello,pat1"
[2]=> "test,pat2"
[3]=> "test,pat2"
[4]=> "foo,pat3"
[5]=> "foo,pat3"
[6]=> "foo,pat3"
....
}
I would like to push it into another array so the output of the array2 is as follow:
array(7) {
[0]=> "hello,pat1"
[1]=> "test,pat2"
[2]=> "foo,pat3"
[3]=> "foo,pat3"
[4]=> "foo,pat3"
[5]=> "hello,pat1"
[6]=> "test,pat2"
.....
}
What I want is to push them in the following pattern: 1 "pat1" 1 "pat2" and 3 "pat3", and repeat this pattern every 5 elements.
while ( !empty( $array1 ) )
$a = explode(",",$array1[$i]);
if($a[1]=='pat1' &&)
push && unset
elseif($a[1]=='pat2' &&)
push && unset
elseif($a[1]=='pat3' and < 5)
push && unset and reset pattern counter
}
What would be a good way of doing this?
Any idea will be appreciate it.
Time for some fun with the iterators of the Standard PHP Library :-)
<?php
$array1 = array (
"hello1,pat1", "hello2,pat1", "hello3,pat1",
"test1,pat2", "test2,pat2",
"foo1,pat3", "foo2,pat3", "foo3,pat3",
"foo4,pat3", "foo5,pat3", "foo6,pat3"
);
// "group by" patN
$foo = array();
foreach($array1 as $a) {
// feel free to complain about the # here ...to somebody else
#$foo[ strrchr($a, ',') ][] = $a;
}
// split pat3 into chunks of 3
$foo[',pat3'] = array_chunk($foo[',pat3'], 3);
// add all "groups" to a MultipleIterator
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
foreach($foo as $x) {
$mi->attachIterator( new ArrayIterator($x) );
}
// each call to $mi->current() will return an array
// with the current items of all registered iterators
foreach ($mi as $x) {
// "flatten" the nested arrays
foreach( new RecursiveIteratorIterator(new RecursiveArrayIterator($x)) as $e) {
echo $e, "\n";
}
echo "----\n";
}
I think I'd set respective counters with respective incrementation. Since php will cast float keys to integers, you can just increment the ,pat3 items with .33 instead of 1. Then, to flatten the result, just use array_merge() with the splat operator.
Code: (Demo)
$array = [
"hello1,pat1",
"hello2,pat1",
"test3,pat2",
"test4,pat2",
"foo5,pat3",
"foo6,pat3",
"foo7,pat3",
];
$counters = [',pat1' => 0, ',pat2' => 0, ',pat3' => 0];
foreach ($array as $value) {
$end = strrchr($value, ',');
$groups[$counters[$end]][] = $value;
$counters[$end] += ($end === ',pat3' ? .33 : 1);
}
var_export(array_merge(...$groups));
Output:
array (
0 => 'hello1,pat1',
1 => 'test3,pat2',
2 => 'foo5,pat3',
3 => 'foo6,pat3',
4 => 'foo7,pat3',
5 => 'hello2,pat1',
6 => 'test4,pat2',
)
Related
If I have this array in PHP:
array(3) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
}
How can I convert this single array into a multidimensional array? What is the quickest way? So I can access this array like:
$array["first"]["second"]...
I want to be able to then set a value to this index like:
$array["first"]["second"]["third"] = "example";
I thought that I need a for loop or a recursive function but I have no idea how to start.
It wasn't quite as simple as I had imagined to begin with. The key to it was doing the process backwards - starting with the last array and then wrapping it in more arrays until you get back to the top level.
$array = array("first", "second", "third");
$newArr = array();
//loop backwards from the last element
for ($i = count($array)-1; $i >= 0 ; $i--)
{
$arr = array();
if ($i == count($array)-1) {
$val = "example";
$arr[$array[$i]] = $val;
}
else {
$arr[$array[$i]] = $newArr;
}
$newArr = $arr;
}
var_dump($newArr);
echo "-------".PHP_EOL;
echo $newArr["first"]["second"]["third"];
Demo: http://sandbox.onlinephpfunctions.com/code/0d7fa30fde7126160fbcc0e80e5727f17b19e39f
I'm trying to sum values from the array from certain ranges provided by another array.
I've tried with this function
function sumArray($array, $min, $max) {
$sum = 0;
foreach ($array as $k => $v) {
if ($k >= $min && $k <= $max) {
$sum += $v;
}
}
return $sum;
}
and this works if i hardcode numbers of course, but i can't figure out how to make this work in a loop
So I have this dates array
array(3) {
["June"]=> int(4)
["July"]=> int(31)
["August"]=> int(29)
}
and i have this daily_values array
array(64) {
[0]=> int(8)
[1]=> int(6)
[2]=> int(10)
[3]=> int(15)
[4]=> int(10)
[5]=> int(9)
[6]=> int(9)
.
.
.
[63] => int(10)
Now what I want to do here is:
based on how many entries are in for example June which is 4 in this case I want to get the sum of values in daily_values array like this:
first loop iteration will sum values in daily_values array from 0 to 3, the second loop iteration will sum values from 4 to 34 and third loop iteration will sum values from 35 to 63 and so on and so on.
So the final thing I want from all this is to have an array which will be like this
["sum of 0,3", "sum of 4,34", "sum of 35,63"]
Just a note here, this array is much bigger, but I cut it short just for question purposes.
I tried to understand your question and here is what I think you are trying to achieve.
I created a similar test and it works fine. Hope it helps you in someway.
<?php
$june = [1,1,1,1];
$july = [1,1];
$august = [1,1,1,1];
$months = array(
'June' => $june,
'July' => $july,
'August' => $august,
);
$daily = [1,1,1,1,5,5,10,10,10,10,2,2,2,2,2];
$sum_arr = array();
$i = 0;
foreach($months as $key=>$month){
$month_count = $month;
$month_sum = 0;
while($month_count > 0){
$month_sum += $daily[$i];
$i++;
$month_count--;
}
$sum_arr[$key] = $month_sum;
}
echo '<pre>';
print_r($sum_arr);
?>
How to group repeated array values in an array using PHP?
I have an array like this
array[0]=203,
array[1]=204,
array[2]=204,
array[3]=203,
array[4]=203,
array[5]=205
I need results like
[203]=1,
[204]=2,
[203]=2,
[205]=1
i want the count of continuously repeating array values
One option to your expected output is to create a indexed array with the associative array below it.
This will create this kind of array:
array(4) {
[0]=>
array(1) {
[203]=>
int(1)
}
[1]=>
array(1) {
[204]=>
int(2)
}
[2]=>
array(1) {
[203]=>
int(2)
}
[3]=>
array(1) {
[205]=>
int(1)
}
}
This is not what you wanted but it is what is possible.
The code loops and keeps track of what the previous value is, if it's the same it will count up the value, else create a new indexed and associative array with value 1.
$array =[203,204,204,203,203,205];
$i=-1;
$prev = null;
$new=[];
foreach($array as $val){
if($val != $prev){
$i++;
}
if(!isset($new[$i][$val])){
$new[$i][$val] =1;
}else{
$new[$i][$val]++;
}
$prev = $val;
}
var_dump($new);
https://3v4l.org/W2adN
array[0]=203;
array[1]=204;
array[2]=204;
array[3]=203;
array[4]=203;
array[5]=205;
$new_array = array();
foreach ($array as $key => $value) {
if(empty($new_array[$value])){
$new_array[$value] = 1;
}else{
$new_array[$value]++;
}
}
/*Now in the array $new_array you have the count of continuously repeating array values*/
This can be done in one line of code using array_count_value function in php.
$arr[0]=203;
$arr[1]=204;
$arr[2]=204;
$arr[3]=203;
$arr[4]=203;
$arr[5]=205;
$result = array_count_values( $arr );
var_dump( $result );
output
array (size=3)
203 => int 3
204 => int 2
205 => int 1
Its my first time working with multidimensional arrays in php. I need to change the second number in each sub array.
What I want is to check if the Id in the array matches the Id from the database. When the two match I want to change the 2nd entry in the sub array by adding a number to it. If the Id from the query does not match anything in the list I want a new sub array to be pushed to the end of the array with the values of Id and points_description.
Also, if its helpful, my program right now does find the matches. The only thing is, it does not update the 2D array.
$array = array(array());
while ($row_description = mysqli_fetch_array($query_description)) {
$check = 1;
$is_match = 0;
foreach ($array as $i) {
foreach ($i as $value) {
if ($check == 1) {
if ($row_description['Id'] == $value) {
//$array[$i] += $points_description;
$is_match = 1;
}
}
$check++;
$check %= 2; //toggle between check and points
}
}
if ($is_match == 0) {
array_push($array, array($row_description['Id'], $points_description));
}
}
I feel like Im doing this so wrong. I just want to go through my 2D array and change every second value. The expected output should be a print out of all the Ids and their corresponding point value
I hope this is helpful enough.
Example: $row_description['Id'] = 2 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1))
if $row_description['Id'] = 3 and $array = array(array(2,1), array(5,1) , array(6,1))
output should be $array = array(array(2,4), array(5,1) , array(6,1),array(3,3))
By default PHP will copy an array when you use it in a foreach.
To prevent PHP from creating this copy you need to use to reference the value with &
Simple example :
<?php
$arrFoo = [1, 2, 3, 4, 5,];
$arrBar = [3, 6, 9,];
Default PHP behavior : Make a copy
foreach($arrFoo as $value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
*/
ByReference : Don't create the copy :
foreach($arrFoo as &$value_foo) {
foreach($arrBar as $value_bar) {
$value_foo *= $value_bar;
}
}
var_dump($arrFoo);
/* Output :
array(5) {
[0]=>
int(162)
[1]=>
int(324)
[2]=>
int(486)
[3]=>
int(648)
[4]=>
&int(810)
}
*/
In the example below $list is an array created by user input earlier in the code, and some slots the user has input nothing. I want to skip the empty items, so the commas aren't created in the output.
$list = array("first", "second", "", "", "fifth", "sixth", "", "");
foreach ($list as $each){$places .= $each . ",";}
results
first,second,,,fifth,sixth,,,
result I want
first,second,fifth,sixth
Got a solution. It looks like this:
$list = array_filter($list);
$places .= implode (",",$list);
To ignore the empty values, you can use
$list = array_filter($list);
Results
Array
(
[0] => first
[1] => second
[4] => fifth
[5] => sixth
)
Source: Mark
array_filter, when passed no second parameter, will remove any empty entries. From there you can proceed as normal:
foreach (array_filter($list) as $each){
$places .= $each . ',';
}
Though you can also use implode if you're just turning it in to a CSV:
$places .= implode(',', array_filter($list));
Side Note Though in this case array_filter may work, it is worth noting that this removes entries that result in a "falsy" result. That is to say:
$list = array_filter(array('foo','0','false',''));
// Result:
// array(2) {
// [0]=>
// string(3) "foo"
// [2]=>
// string(5) "false"
// }
So be careful. If the user could potentially be entering in numbers, I would stick with comparing empty. Alternatively you can use the second parameter of array_filter to make it more explicit:
function nonEmptyEntries($e)
{
return ((string)$e) !== '';
}
$list = array_filter($list, 'nonEmptyEntries');
// result:
//array(3) {
// [0]=>
// string(3) "foo"
// [1]=>
// string(1) "0"
// [2]=>
// string(5) "false"
//}
(Note that the 0 entry is kept, which differs from a blanket array_filter)