PHP iterate multi dimensional array with missing rows - php

Suppose I have 2d array, where only some rows actually have some values in the columns, whereas other rows don't have anything.
For example: only rows 5 and 9 have some data, other rows are empty. Number of columns is fixed - 6
I have not declared any size for the 2D array.
I want to find all fields whose value is 10.
for ($t1=0; $t1 < count($array); $t1++) {
for ($t2=0; $t2 < 6; $t2++) {
if($array[$t1][$t2] == 10) {
// do something
}
}
}
Now this code won't work because count($array) will be 2, so it will never iterate for rows 5 and 9.
I also need to get the index at which I found a match.
How can I write code to make it work in this case?

You can effectively use foreach in this case:
foreach($array as $s => $arrayElement) {
for($t=0; $t<6; $t++) if ($arrayElement[$t] == 10) {
// do something - $s is the row index, $t is the column index
}
}

I think , you have a problem in defining array. May be , you can use this script.
<?php
$cars = array(
array(
"Volvo",
22,
18
),
array(
"BMW",
15,
13
),
array(
"Saab",
5,
2
),
array(
"Land Rover",
17,
15
),
array(
"Mercedes",
22,
19
)
);
$length = count($cars);
for ($i = 0; $i < $length; $i++) {
for ($j = 0; $j < 3; $j++) {
echo $cars[$i][$j] . "</br>";
}
}
?>
I hope , it will solve your problem.

Related

How to deduct specific array "values from another values" in PHP?

I have an array like this:
$datas = array(54,12,61,98,88,
92,45,22,13,36);
I want to write a loop which can deduct values of an array like below and show it with echo:
$datas[5]-$datas[0] for this line the result will be 92-54 "38"
$datas[6]-$datas[1] for this line the result will be 45-12 "33"
$datas[7]-$datas[2] ... "-39"
my codes are:
<?php
$smonth1= 0;
$emonth1=5;
for ($i = 5; $i > 0; $i-- ) {
$result = array_diff($datas[$emonth1], $datas[$smonth1]);
echo (implode ($result))."<br/>" ;
$smonth1++ ;
$emonth1++;
}
?>
but I couldn't get the result I don't know why. I am fresh in php. Can you help me??
Assuming the input array always has an even number of values in it (which I think is the only way this scenario could logically work), then you can simply count how many items are in the array, and then loop through it, taking the nth item and subtracting it from the n+(total / 2)th item.
$data = array(54,12,61,98,88,
92,45,22,13,36);
$halfway = count($data)/ 2;
for ($i = 0; $i < $halfway; $i++)
{
$j = $i + $halfway;
echo $data[$j] - $data[$i].PHP_EOL;
}
Demo: https://3v4l.org/ictDT
Basically, you want something like this
<?php
$data = [
54, 12, 61, 98, 88,
92, 45, 22, 13, 36
];
$offset = 5;
for ($i = 0; $i + $offset < count($data); $i++) {
echo $data[$i + $offset] - $data[$i];
echo "\n"; // or <br/> if you run it in browser
}

I want to get elements from array in order: three, four, three, four and so on

I want to get elements from an array like this: get first three element, then four elements, then again three elements, and again four, and so on in a loop.
For example:
0 1 2
3 4 5 6
7 8 9
10 11 12 13
and so on....
I tried something like this:
foreach($items as $key => $item) {
if($key <= 2) {
echo 'test';
}
if($key > 2 && $key < 6) {
echo 'other test';
}
if($key > 6 && $key < 9) {
echo 'test';
}
}
However, I don't want to use if() like these, because I don't know how many items will be in the array: it comes from a database.
I think, I need something like array_chunk($items, 3) but for size parameter I need 3 and 4 in loop
Could be like this you can make another array of specifying the number of elements you want in each iteration.
<?php
$number_of_elements = [3,4,3,4];
$your_array = ['a', 'b','c','d','e'];
foreach($number_of_elements as $number){
for($i = 0; $i<=$number; $i++){
$result = $your_array[$i];
print_r($result);
}
print_r('<br>');
}
In JavaScript you can solve your problem using a for loop and the built in slice function of the array.
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
let offset = 0;
for(let i = 0; i < array.length;){
offset = offset === 3 ? 4 : 3;
const subArray = array.slice(i, i + offset);
console.log(subArray);
i += offset;
}

Randomly pick array values, add them up, until you get a certain value in php

I have the following array with undefined number of elements
$marks=array('2','4','9','3');
target=50;
I want to randomly loop through the array, add up the values I fetch until the total is my target.
$total=0; /////initialize total
for($i=0;$i<=sizeof($marks);++$i)
{
/////////Pick up random values add them up until $total==$target
/////////return the new array with selected elements that sums up to
/////////target
}
I hope my question is clear, also note that the loop should not iterate too many times since the elements might never add up to the total. I have tried adding the items in line but to no avail. Thanks in advance
I think this'll work for you and always return you value of count to be 50 only
$marks = array(6,7,9,6,7,9,3,4,12,23,4,6,4,5,7,8,4);
$target = 50;
function sum($marks, $target) {
$count = 0;
$result = [];
for ($i = 0; $i <= $target; $i++) {
if ($count < $target) {
$add = $marks[array_rand($marks)];
$count = $count + $add;
$result['add'][] = $add;
} elseif ($count == $target) {
break;
} elseif ($count >= $target) {
$extra = $count - $target;
$count = $count-$extra;
$result['extra'] = $extra;
}
}
return $result;
}
print_r(sum($marks, $target));
The way you describe your logic, a while loop might make more sense:
<?php
$marks = array(2, 4, 9, 3);
$target = 50;
$sum = 0;
$i = 0; // to keep track of which iteration we're on
// PHP can natively randomize an array:
shuffle($marks);
while ($sum < $target && $i < count($marks)) {
$sum += $marks[$i];
$i++; // keep track of which iteration we're on
}
// after the loop, we've either added every number in $marks,
// or $sum >= $target
Don't forget that it might exceed $target without ever being equal to it, as Dagon pointed out in a comment.
Look into PHP's native array shuffle: https://secure.php.net/manual/en/function.shuffle.php
This may be a good alternative for the above answer.
Why I say so is that I have set it in such a way that it doesn't let the total go over the target, and when there is such a situation, the current number in the array is decremented by one and added as a new element so that if there is no possible number in the stack, there will be one eventually making this loop not go on infinitely. :)
<?php
$marks = ['2', '4', '9', '3'];
$target = 50;
$total = 0;
$numbersUsed = [];
while($total != $target) {
$index = rand(0, count($marks) - 1);
$number = $marks[$index];
if($number + $total > $target) {
$number = 0;
$marks[] = $marks[$index] - 1;
} else {
$numbersUsed[] = $number;
}
$total += $number;
echo $total . "\n";
}
// To see which numbers were used:
print_r($numbersUsed);
?>
Testing:
Starting with the array ['2', '4', '9', '3'],
We loop and get the result:
4 13 17 20 22 31 35 44 46 48 48 48 48 50
And we get this array which includes the numbers used to get the final result:
Array
(
[0] => 4
[1] => 9
[2] => 4
[3] => 3
[4] => 2
[5] => 9
[6] => 4
[7] => 9
[8] => 2
[9] => 2
[10] => 2
)

How to compress an array?

Lets say, I have an array with 1000 values (integers). And I need from this array to have an array with f.e. 400 values (the number can be changed, f.e. 150, etc.).
So I need to return each 2.5th array value, i.e. 1st, 3rd, 6th, 8th, 11th, etc.
Is this somehow possible?
I dont need a code, I just need some way, how to do it.
EDITED:
My array is array of elevations (from another array with GPS coordinates). And I want to draw a 2D model of elevation. Lets say, my map will always have 400px width. 1px = 1 point of elevation. Thats why I need each 2.5th elevation value...
Like this:
You don't want the 2.5th one. You effectively want to divide the set into blocks of five and get the first and third from each set.
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
You want the first and third columns.
This is PHP, so we've got 0-based arrays.
We can divide it into groups of 5 using the modulo operator %. We can then see if the return value is 0 (i.e. it's in the first column) or 2 (i.e. it's in the third column).
I'm going to presume your array has numeric keys starting from 0.
// PHP 5.6
$filtered = array_filter($array, function($value, $key) {
$mod = $key % 5;
return ($mod === 0) || ($mod === 2);
}, ARRAY_FILTER_USE_BOTH);
// pre-PHP 5.6
$filtered = array();
foreach ($array as $key => $value) {
$mod = $key % 5;
if (($mod === 0) || ($mod === 2)) {
$filtered[$key] = $value;
}
}
var_dump($filtered);
How about using the modulo % operator?
Say you want to make 1000 into 200 values, loop through all the items in the array and keep a counter, if the counter % 5 == 0 then put that value into a new array, or if != 0 then remove from array. We use modulo 5 because 1000 / 200 = 5.
Below is the way to start with. It does not ensure that first and last elements are included in the output and, probably, has some other glitches. But since you requested the idea, here you go—array_reduce:
$a=[1,2,3,4,5,6,7,8,9,10,11,12]
$step = 2.5;
$i = 0;
$r = array_reduce($a, function($memo, $curr) use(&$i, $step) {
if($i === round($step * count($memo))) {
$memo[] = $curr;
}
$i++;
return $memo;
}, []);
print_r($r);
/*
Array
(
[0] => 1
[1] => 4
[2] => 6
[3] => 9
[4] => 11
)
*/
Hope it helps.
This should be pretty close to what you seem to be looking for. It will collect whichever values are closest (rounding down) to the float values.
$list = range(1,1000);
$targetSize = 300;
$new = array();
$step = count($list) / $targetSize;
$curStep = 0;
for( $i = 0; $i < count($list); $i++ ) {
$curStep++;
if( $curStep > $step ) {
$new[] = $list[ floor($i) ];
$curStep -= $step;
}
}
So this is it:
$arr = range(1, 1387); // f.e.
$cnt = 296; // f.e.
$new = array();
$max = count($arr);
$step = $max / $cnt;
for ($i = 0; $i < $max; $i += $step) {
$new[] = round($arr[(int)$i]);
}

Creating an N x N array of integers that "staircase" and "wrap around"

I am having trouble trying to figure out how to get data ordered like below. The total numbers don't matter; it would follow the same pattern from any number in the logical order of 0, 1, 2, 3, 4, 5, 6, etc. So essentially, starting at 0, 2, 3, 4, etc. where 1 would be placed after the maximum number, and where 0 can be a variable I set statically. I am having issues with progressing all the way to max number and then continuing, e.g.
..., 97, 98, 99, 100, 1, 2, ...
and then progressing with the order,
..., 98, 99, 100, 1, 2, 3, ...
and so on until 1, 2, 3, 4, 5, 6, ...
and store this all into the multidimensional array below.
$set = array(
array('0','0','0','0','0','0','0','0','0','0','0'),
array('0','2','3','4','5','6','7','8','9','10','1'),
array('0','3','4','5','6','7','8','9','10','1','2'),
array('0','4','5','6','7','8','9','10','1','2','3'),
array('0','5','6','7','8','9','10','1','2','3','4'),
array('0','6','7','8','9','10','1','2','3','4','5'),
array('0','7','8','9','10','1','2','3','4','5','6'),
array('0','8','9','10','1','2','3','4','5','6','7'),
array('0','9','10','1','2','3','4','5','6','7','8'),
array('0','10','1','2','3','4','5','6','7','8','9'),
array('0','1','2','3','4','5','6','7','8','9','10'),
);
I did the above because I couldn't figure out a looping pattern; if I could figure that out I wouldn't need to enter in the data manually and could create a form by which any number could be chosen, following this pattern.
Notice that other than the first row and column, each row is just the previous shifted left, with the next value added on:
$max = 10;
// First row (full of 0)
$set = array(array_fill(0, $max + 1, 0));
$row = array();
for($i = 1; $i <= $max; $i++)
$row[] = $i;
$row[] = 1; // $row = [2,3,4,...,$max,1]
for($i = 0; $i < $max; $i++){
$set[] = array_merge(array(0), $row);
$row = array_map(function($x) use ($max){ // Requires PHP 5.3
$result = ($x + 1) % $max;
return 0 === $result ? $max : $result;
}, $row);
}
Codepad
It's of course fairly trivial to make this store strings instead of integers if you require that.
$array = array();
$max = 10;
for ($i = 0; $i < $max; $i++)
{
$num = $i + 2;
$array[$i][] = 0;
for ($j = 0; $j < $max; $j++)
{
if ($num == $max + 1)
$num = 1;
$array[$i][] = $num;
$num++;
}
}
var_dump($array);

Categories