I have an array like that:
[0] => Array
(
[sendby] => 3
[refresh] => 0
[last] => 0
)
[1] => Array
(
[sendby] => 3
[refresh] => 1
[last] => 1
)
[2] => Array
(
[sendby] => 8
[refresh] => 1
[last] => 1
)
I want the value last to be 1 when the value sendby (here 3 and 8) is the last of the entire array! How can I do that?
Get the last 2 value and compare with array [3,8]
// get array of sendby values
$temp = array_column($array, 'sendby');
// get array with two last values
$temp = array_slice($temp, -2);
// Check
if ($temp == [3,8]) {
$value = 1;
}
else {
$value = 0;
}
or in one line
$value = array_slice(array_column($array, 'sendby'), -2) == [3,8] ? 1 : 0;
demo
Update on base of comments
// get array with two last values
$temp = array_slice(array_column($array, 'sendby'), -2);
foreach($array as &$x) {
// If current send by is in $temp array
if(in_array($x['sendby'], $temp)) {
$x['last'] = 1;
}
else {
$x['last'] = 0;
}
}
print_r($array);
You can use an array to assist the existing ocurrences of that id. I have an working example (Tested on php sandbox):
$array = array(
0 => array
(
'sendby' => 3,
'refresh' => 0,
),
1 => array
(
'sendby' => 3,
'refresh' => 1,
),
2 => array
(
'sendby' => 8,
'refresh' => 1,
)
);
$ocurrences = [];
foreach($array as $key => $elem ){
$id = $elem['sendby'];
if (isset($ocurrences[$id])) {
$array[$ocurrences[$id]]['last'] = 0;
$array[$key]['last'] = 1;
$ocurrences[$id] = $key;
} else {
$ocurrences[$id] = $key;
$array[$key]['last'] = 1;
}
}
echo print_r($array, 1);
The result:
Array
(
[0] => Array
(
[sendby] => 3
[refresh] => 0
[last] => 0
)
[1] => Array
(
[sendby] => 3
[refresh] => 1
[last] => 1
)
[2] => Array
(
[sendby] => 8
[refresh] => 1
[last] => 1
)
)
Basically I used an array with the ocurrences of the 'sendby' index of the array. The $occurences array has the elements with the key of the last checked element.
Lets suppose your array is $array;
You could iterate through it and if it's the last element, then set [last] to 1, else set to 0;
Try to run the below code after your array is populated.
$i =1;
foreach($array as $ar) {
$ar->last = ($i == count($array) && ($ar->sendby == 3 || $ar->sendby == 8)) ? 1 : 0;
$i++;
}
$count = count($arr) ;
$i = 0;
foreach($arr as $key=>$val) {
if(++$I === $count) {
echo "last element" ;
}
}
Related
Goal: Generate an array that includes only those 'columns' with data, even though a 'header' may exist.
Example Data:
Array (
[HeaderRow] => Array (
[0] => Employee [1] => LaborHours [2] => 0.1 [3] => 0.25 [4] => 0.5 [5] => 0.8
)
[r0] => Array (
[0] => Joe [1] => 5 [2] => [3] => [4] => 50 [5] =>
)
[r1] => Array (
[0] => Fred [1] => 5 [2] => 10 [3] => [4] => [5] =>
)
)
Desired Output:
Array (
[HeaderRow] => Array (
[0] => Employee [1] => LaborHours [2] => 0.1 [4] => 0.5
)
[r0] => Array (
[0] => Joe [1] => 5 [2] => [4] => 50
)
[r1] => Array (
[0] => Fred [1] => 5 [2] => 10 [4] =>
)
)
So, in this very dumbed down example, the HeaderRow will always have data, but if both c0 and c1 are empty (as is the case for [3] and [5]) then I want to remove. I tried iterating through with for loops like I would in other languages, but that apparently doesn't work with associative arrays. I then tried doing a transpose followed by two foreach loops, but that failed me as well. Here's a sample of my for loop attempt:
Attempt with For Loop
for ($j = 0; $j <= count(reset($array))-1; $j++) {
$empty = true;
for ($i = 1; $i <= count($array)-1; $i++) {
if(!empty($array[$i][$j])) {
$empty = false;
break;
}
}
if ($empty === true)
{
for ($i = 0; $i <= count($array); $i++) {
unset($array[$i][$j]);
}
}
}
return $array;
Attempt with transpose:
$array = transpose($array);
foreach ($array as $row)
{
$empty = true;
foreach ($row as $value)
{
if (!empty($value))
{
$empty = false;
}
}
if ($empty) {
unset($array[$row]);
}
}
$array = transpose($array);
return $array;
function transpose($arr) {
$out = array();
foreach ($arr as $key => $subarr) {
foreach ($subarr as $subkey => $subvalue) {
$out[$subkey][$key] = $subvalue;
}
}
return $out;
}
I know the transpose one isn't terribly fleshed out, but I wanted to demonstrate the attempt.
Thanks for any insight.
We can make this more simpler. Just get all column values using array_column.
Use array_filter with a custom callback to remove all empty string values.
If after filtering, size of array is 0, then that key needs to be unset from all
subarrays.
Note: The arrow syntax in the callback is introduced since PHP 7.4.
Snippet:
<?php
$data = array (
'HeaderRow' => Array (
'0' => 'Employee','1' => 'LaborHours', '2' => 0.1, '3' => 0.25, '4' => 0.5, '5' => 0.8
),
'r0' => Array (
'0' => 'Joe', '1' => 5, '2' => '','3' => '', '4' => 50, '5' => ''
),
'r1' => Array (
'0' => 'Fred', '1' => 5,'2' => 10, '3' => '', '4' => '', '5' => ''
)
);
$cleanup_keys = [];
foreach(array_keys($data['HeaderRow']) as $column_key){
$column_values = array_column($data, $column_key);
array_shift($column_values); // removing header row value
$column_values = array_filter($column_values,fn($val) => strlen($val) != 0);
if(count($column_values) == 0) $cleanup_keys[] = $column_key;
}
foreach($data as &$row){
foreach($cleanup_keys as $ck){
unset($row[ $ck ]);
}
}
print_r($data);
It figures, I work on this for a day and have a moment of clarity right after posting. The answer was that I wasn't leveraging the Keys.:
function array_cleanup($array)
{
$array = transpose($array);
foreach ($array as $key => $value)
{
$empty = true;
foreach ($value as $subkey => $subvalue)
{
if ($subkey != "HeaderRow") {
if (!empty($subvalue))
{
$empty = false;
}
}
}
if ($empty) {
unset($array[$key]);
}
}
$array = transpose($array);
return $array;
}
How to move values from 2nd array into the empty places of 1st array
1st array as below
Array
(
[0] => 1
[1] =>
[2] => 4
[3] =>
)
2nd array as below
Array
(
[0] => 5
[1] => 9
)
I want output as merging 2nd array into 1st as shown below
Array
(
[0] => 1
[1] => 5
[2] => 4
[3] => 9
)
I have tried below code.....
for($i=0; $i<$count; $i++){
for($j=$i; $j<=$i; $j++)
if(empty($assign_taskk[$i])){
$assign_taskk[$i] = $taskkk[$i];
}
}
plz help me out for same
Lets say your arrays look like:
$a1 = [
0 => 1,
1 => null,
2 => 4,
3 => null,
];
$a2 = [
0 => null,
1 => 5,
2 => null,
3 => 9,
];
Then you can iterate over first array and add values from the second one when needed:
foreach ($a1 as $k => $v) {
if (empty($v) && !empty($a2[$k])) {
$a1[$k] = $a2[$k];
}
}
Another way to do it using below way-
<?php
$arr1= [1,null,4,null];
$arr2 = [null,5,null,9];
$result = array_values(array_filter($arr1) + array_filter($arr2));
print_r($result)
?>
DEMO: https://3v4l.org/R4aeE
Hi #amod try this
$_newArray = array_values(array_filter($array1) + array_filter($array2));
print_r($_newArray);
You can use below code for this:
$firstArray = [1,'',4,''];
$secondArray = [5,9];
$secondArrayCounter = 0;
foreach($firstArray as $key => $value) {
if (empty($value)) {
$firstArray[$key] = $secondArray[$secondArrayCounter];
$secondArrayCounter++;
}
}
print_r($firstArray);
Hope it helps you.
This question already has answers here:
Php recursive array counting
(7 answers)
Closed 4 months ago.
I try to make recursive function to count elements on array "levels". But can't do that for two hours already. Check example array:
Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
[1] => Array ( )
)
[1] => Array (
[0] => Array (
[0] => Array (
[0] => Array ( )
[1] => Array ( )
)
)
)
)
The resulting array that count elements on different levels will be:
Array ([0] => 2, [1] => 3, [2] => 3, [3] => 2)
I made function for count total array elements, but no idea how to count each "level"
function countTotalArr($arr, $lvl) {
if ($lvl != 0) $cnt = 1;
else $cnt = 0; // don't count zero level
for ($i = 0; $i < count($arr); $i++)
$cnt += countArr($arr[$i], $lvl + 1);
return $cnt;
}
$total = countTotalArr($referralsCount, 0);
Another solution using while:
// $array is your array at the beginning of iteration
$depthMap = [];
$currentDepth = 0;
while(true) {
$depthMap[$currentDepth] = count($array);
$carry = [];
foreach($array as $item) {
if(is_array($item)) {
$carry = array_merge($carry, $item);
}
}
if(count($carry) < 1) {
break;
}
$array = $carry;
$currentDepth++;
}
Try this code:
<?php
$array = Array (
0 => Array (
0 => Array (
0 => Array ( ) ,
1 => Array ( ) ,
) ,
1 => Array ( ) ,
) ,
1 => Array (
0 => Array (
0 => Array (
0 => Array ( ),
1 => Array ( ),
),
),
) ,
);
function countTotalArr($arr, $lvl)
{
$result = array();
$countOnLevel = count($arr);
$result[$lvl] = $countOnLevel;
$tempArray = array();
foreach($arr as $index => $singleArray)
{
foreach($singleArray as $singleSubArray)
if(is_array($singleSubArray))
$tempArray[] = $singleSubArray;
}
if(!empty($tempArray))
{
$levelTemp = $lvl + 1;
$result = array_merge($result, countTotalArr($tempArray, $levelTemp));
}
return $result;
}
$total = countTotalArr($array, 0);
echo '<pre>';
print_r($total);
Result of print_r($total) is:
Array
(
[0] => 2
[1] => 3
[2] => 3
[3] => 2
)
Why $val is Array(1), but not the numeric value? I expected that $selected as $k => $val should return each line from the array $selected. Thus, $k must be a numeric key (it is) and $val must be corresponding numeric value (but it's an array instead of simple integer).
So, how do I correctly save sorted keys and values in array $ind and $ranks?
<?php
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = array($i => rand(0,5));
}
arsort($selected);
$ind = array();
$rank = array();
foreach($selected as $k => $val) {
$ind[] = $k;
$rank[] = $val;
}
?>
UPDATE:
For incstance, this code..
for ($i=0; $i<5; $i++) {
$selected[$i] = rand(0,5);
}
provided the array:
[0] => 5, [1] => 3, [2] => 2, [3] => 5, [4] => 3
Once I sorted it, initial keys are deleted, right? How can I find initial keys [0]-[4] of randomly generated values after sorting the array?
I think your likely solution is to change
$selected[] = array($i => rand(0,5));
to
$selected[] = rand(0,5);
Doing so will yield $ind and $rank like this:
Array
(
[0] => 0
[1] => 3
[2] => 2
[3] => 4
[4] => 1
)
Array
(
[0] => 4
[1] => 3
[2] => 1
[3] => 0
[4] => 0
)
The best way to do what you want, is to just use the resultant array, for example:
$selected
Array
(
[1] => 5
[2] => 5
[4] => 4
[0] => 2
[3] => 1
)
I think this is what you need
for ($i=0; $i<5; $i++) {
$selected[$i] = rand(0,5);
}
Your array structure will look like this:
array(
0 => array(0 => 1),
1 => array(1 => 4),
...
)
because you're assigning an array here:
$selected[] = array($i => rand(0,5));
You just want this instead:
$selected[] = rand(0,5);
Hi I am not pretty much sure what you are trying to do but following code is creating an array of arrays.
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = array($i => rand(0,5));
}
So $val will be an array. You can try following code:
$selected = array();
for ($i=0; $i<5; $i++) {
$selected[] = rand(0,5);
}
Thanks
I have the following array with multiple levels. I wish to get the sum total of [price], [adults] and [childern] but have not been able traverse the levels.
The answer I should get with this example is price=380 adults=5 and children=1
Array (
[8] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 0
[1] => 0
)
[prices] => Array (
[0] => 50
[1] => 50
)
[price] => 130
[supp] => 30
)
[3] => Array (
[num_rooms] => 1
[adults] => Array (
[0] => 1
)
[prices] => Array (
[0] => 100
)
[price] => 150
[supp] => 50
)
)
[1] => Array (
[2] => Array (
[num_rooms] => 2
[adults] => Array (
[0] => 1
[1] => 1
)
[children] => Array (
[0] => 1
[1] => 0
)
[prices] => Array (
[0] => 75
[1] => 75
)
[price] => 170
[supp] => 20
)
)
)
Thanks
Two loops and a helper array:
$sums = array ( 'price' => 0, 'adults' => 0, 'children' => 0 );
foreach($array as $outer) {
foreach($outer as $inner) {
$sums['price'] += $inner['price'];
$sums['adults'] += array_sum($inner['adults']);
$sums['children'] += array_sum($inner['children']);
}
}
print_r($sums);
With a more dynamic version of the inner loop:
foreach($array as $outer) {
foreach($outer as $inner) {
foreach($sums as $key => &$v)
$v += is_array($inner[$key])
? array_sum($inner[$key])
: $inner[$key];
}
}
This should work:
$price = 0;
$adults = 0;
$children = 0;
foreach($arr as $l1_key => $l1_value) // iterates over the first level array
{
foreach($l1_value as $l2_key => $l2_value) // iterates over second level arrays
{
$price += $l2_value['price']; // add up price totals
foreach($l2_value['adults'] as $value) // iterate through adults array values
{
$adults += $value; // sum up adult count
}
foreach($l2_value['children'] as $value) // iterate through children array values
{
$children += $value; // sum up children count
}
}
}
// now $price, $adults, and $children contain the totals for each
I didn't test this code but at the same time I don't know how you got 380.. I'm seeing 350?
$sums = getSum($arr);
print_r($sums);
function getSum($arr) {
$sums = array();
$sums2 = array();
$sums['adults'] = 0;
$sums2['adults'] = 0;
$sums['children'] = 0;
$sums2['children'] = 0;
$sums['prices'] = 0;
$sums2['prices'] = 0;
foreach ($arr as $key => $value) {
$do_not_recurse = false;
switch ($key) {
case 'adults':
$do_not_recurse = true;
foreach ($value as $adults)
$sums['adults'] += $adults;
break;
case 'children':
$do_not_recurse = true;
foreach ($value as $children)
$sums['children'] += $children;
break;
case 'prices':
$do_not_recurse = true;
foreach ($value as $price)
$sums['prices'] += $price;
break;
default:
break;
}
if (is_array($value))
$sums2 = getSum($value);
}
$sums['adults'] += $sums2['adults'];
$sums['children'] += $sums2['children'];
$sums['prices'] += $sums2['prices'];
return $sums;
}
Handles any depth or array structure and just picks out the terms with the names you are looking for:
function find($term, $array) {
$count = 0;
foreach ($array as $item)
if (is_array($item)) $count += find($term, $item);
if (isset($array[$term]) {
if (is_array($array[$term])) $count += array_sum($array[$term]);
else $count += $array[$term];
}
return $count;
}
echo count('price', <the array>);
echo count('adults', <the array>);
echo count('children', <the array>);