Undefined offset with count() - php

I have an array $MyArray which has some elements which are also array (lets call them subarrays). I want to know how many elements the subarray with the most elements has. The problem is, that I don't know if the index exists:
max(
#count($MyArray[$i*7]),
#count($MyArray[$i*7+1]),
#count($MyArray[$i*7+2]),
#count($MyArray[$i*7+3]),
#count($MyArray[$i*7+4]),
#count($MyArray[$i*7+5]),
#count($MyArray[$i*7+6])
);
Struckture of $MyArray:
Array(
12 => array (
0 => array ( 0 => 0, 1 => 1, ),
1 => array ( 0 => 13, 1 => 1, ),
2 => array ( 0 => 15, 1 => 1, ),
3 => array ( 0 => 20, 1 => 1, ),
4 => array ( 0 => 69, 1 => 1, )
),
5 => array (
0 => array ( 0 => 55, 1 => 1, ),
1 => array ( 0 => 32, 1 => 1, ),
2 => array ( 0 => 12, 1 => 1, ),
3 => array ( 0 => 21, 1 => 5, )
),
....
)
Can this be done better (faster)?
edit: I know foreach and I don't want to loop over every element in this array. I just want an interval of it. # is used, because I don't know if $MyArray[$i*7 + x] is Null or an array.
$i is a element of [0, 1, 2, 3, 4] (sometimes also 5)

$biggest = 0;
foreach ($MyArray as $value) {
if ($biggest < count($value)) {
$biggest = count($value);
}
}
I see, you want the size of the biggest array in the array, correct?

Simple and old school approach:
<?php
$max = -1;
foreach($MyArray as $subarray)
{
$items = count($subarray);
if($items > $max)
$max = $items;
}
echo $max;
?>
This works best since you only want to know how many elements the subarray with the most elements has.

$max = 0;
foreach ($MyArray as $value) {
$max = max($max,count($value));
}

Try this:
$arr = array();
for ($j=0;$j<=6;$j++) {
if (isset($MyArray[$i*7+$j])) $arr[] = count($MyArray[$i*7+$j]);
}
$result = max($arr);
I don't know exactly what $i refers to though...

// get the interesting part of the array
$chunk = array_intersect_key($input_array, array_flip(range($i*7, $i*7+6)));
// max(count)
$max = $chunk ? max(array_map('count', $chunk)) : 0;

Related

Create new array based on element position

I have an array like so
$dataArray = array(
array( 20800, 21679, 0 ),
array( 15254, 0, 3726 ),
array( 17426, 2973, 0 ),
array( 4391, 37, 0 ),
array( 39194, 435, 0 )
);
I am creating a sub array from this. Any value greater than 2000 becomes a 1, otherwise it becomes a 0.
foreach ($dataArray as $row => $data) {
foreach ($data as $key => $value) {
if($value > 1999) {
$dataArray[$row][$key] = 1;
} else {
$dataArray[$row][$key] = 0;
}
}
}
This produces the following
$dataArray = array(
array( 1, 1, 0 ),
array( 1, 0, 1 ),
array( 1, 1, 0 ),
array( 1, 0, 0 ),
array( 1, 0, 0 )
);
Now what I am trying to do is produce another array that shows the positions of the 1's within the above array. Each row should be represented by a new array. The output I am looking for is this
$dataArray = array(
array( 1, 2 ),
array( 1, 3 ),
array( 1, 2 ),
array( 1 ),
array( 1 )
);
So I can see that row 1 has a 1 in position 1 and 2, row 2 has a 1 in positions 1 and 3 etc.
I wanted to make use of my current loop, so I am trying something like this
$position = array();
foreach ($dataArray as $row => $data) {
foreach ($data as $key => $value) {
if($value > 1999) {
$position[$row] = $key + 1;
$dataArray[$row][$key] = 1;
} else {
$dataArray[$row][$key] = 0;
}
}
}
But this seems way off according to my output. How can I achieve what I am after?
Thanks
<?php
$dataArray = array(
array( 20800, 21679, 0 ),
array( 15254, 0, 3726 ),
array( 17426, 2973, 0 ),
array( 4391, 37, 0 ),
array( 39194, 435, 0 )
);
$endResult = [];
foreach ($dataArray as $key => $value) {
foreach ($value as $subkey => $subvalue) {
if ($subvalue >= 2000) {
$endResult[$key][] = $subkey +1;
}
}
}
print_r($endResult);
Array
(
[0] => Array
(
[0] => 1
[1] => 2
)
[1] => Array
(
[0] => 1
[1] => 3
)
[2] => Array
(
[0] => 1
[1] => 2
)
[3] => Array
(
[0] => 1
)
[4] => Array
(
[0] => 1
)
)
You could use array_map along with array_keys:
$dataArray = [
[1, 1, 0],
[1, 0, 1],
[1, 1, 0],
[1, 0, 0],
[1, 0, 0]
];
$onePositions = array_map(function($row) {
return array_map(function($position) { return $position + 1; }, array_keys($row, 1));
}, $dataArray);
echo '<pre>'; var_dump($onePositions); echo '</pre>';
Demo here
You can make use of the second parameter in the array_keys() function to get the positions after you populate the ones and zeros:
$position = array();
$binary = array();
foreach ($dataArray as $row => $data) {
// if you want to have the positions start at 1 instead of 0
// add a dummy value to the final array
$binary[$row][] = 0;
foreach ($data as $key => $value) {
if($value > 1999) {
$binary[$row][] = 1;
} else {
$binary[$row][] = 0;
}
}
$positions[] = array_keys($binary[$row], 1);
}
Demo Here

PHP Create Multidimensional Array from Corresponding Counts Array

Using PHP (7.1) with the following data and nested loops, I'm trying to get each host to match the corresponding number in the COUNTS array.
HOSTS:
Array (
0 => 'example/search?results1'
1 => 'thisone/search?results2'
2 => 'thesetoo/search?results3'
)
COUNTS:
Array (
0 => '3'
1 => '5'
2 => '7'
)
foreach ( $counts as $count ) {
foreach ( $hosts as $host ) {
$t = $count;
for ($n=0; $n<$t; $n++) {
$results[] = ++$host;
}
continue 2;
}
}
echo 'THESE ARE ALL THE RESULTS:',PHP_EOL,PHP_EOL,var_dump($results);
RESULTS I'M LOOKING FOR:
MULTIDIMENSIONAL ARRAY
Array (
0 => Array (
0 => 'example/search?results1'
1 => 'example/search?results1'
2 => 'example/search?results1'
)
1 => Array (
0 => 'thisone/search?results2'
1 => 'thisone/search?results2'
2 => 'thisone/search?results2'
3 => 'thisone/search?results2'
4 => 'thisone/search?results2'
)
2 => Array (
0 => 'thesetoo/search?results3'
1 => 'thesetoo/search?results3'
2 => 'thesetoo/search?results3'
3 => 'thesetoo/search?results3'
4 => 'thesetoo/search?results3'
5 => 'thesetoo/search?results3'
6 => 'thesetoo/search?results3'
)
)
Notice the number of results per HOSTS corresponds to the COUNTS array.
In the nested for loops above, I'm either getting just one host for all counts or every count for all hosts in a single dimension array. What I need is a multi-dimensional array, but the nested for loop logic is escaping me. I've tried both continue and break in the loops, but no luck. If the loop gets another count, then it skips the host. If it gets another host, then it skips the count.
There is no pattern to either the hosts or the counts array. These will always correspond to each other but they will be random strings/numbers. Thank you for your help.
if count of $hosts and $counts equals:
$result = [];
foreach ($hosts as $i => $host) {
$result[] = array_fill(0, $counts[$i], $host);
}
This question is the perfect usage example for array_map() and array_fill().
$hosts = array(
0 => 'example/search?results1',
1 => 'thisone/search?results2',
2 => 'thesetoo/search?results3',
);
$counts = array(
0 => '3',
1 => '5',
2 => '7',
);
$result = array_map(
function($host, $count) {
return array_fill(0, $count, $host);
},
$hosts,
$counts
);
Try this:
$hosts = array (
0 => 'example/search?results1',
1 => 'thisone/search?results2',
2 => 'thesetoo/search?results3'
);
$counts = array (
0 => '3',
1 => '5',
2 => '7'
);
$results =array();
foreach ( $counts as $count ) {
$key_of_count = array_search( $count, $counts );
for ($i=0; $i < (int)$count; $i++) {
$results[$key_of_count][] = $hosts[$key_of_count];
}
}
echo "<pre>"; print_r($results); echo "</pre>";
If you are looking for way that is done using only loops and not using any fancy array functions, then this might be the answer you are looking for:
$result = [];
foreach($counts as $k=>$count){
$result[$k]='';
for($i=0; $i < $count; $i++){
$result[$k][] = $hosts[$k];
}
}

get set elements from array php

I have array in php :
Array
(
[id] => 1
[comp_id] => 1
[transaction_purpose] => 0
[source_of_funds] => 1
[beneficiary_relationship] => 0
[cus_occupation] => 0
[cus_id_image_2] => 0
[cus_id_image_3] => 0
[ben_id_type] => 0
[ben_id_number] => 1
)
I want to get only array key=>value pair if the valie is 1.
result array should be:
Array
(
[id] => 1
[comp_id] => 1
[source_of_funds] => 1
[ben_id_number] => 1
)
I tried with:
$returnArray = array();
foreach($mainArray as $r){
if($r>0){
array_push($returnArray, $mainArray);
}
}
But, It's giving me 4 times main array. Is there any way to achieve this? Thanks..
Just use array_filter():
$newarray = array_filter($array, function($var) {
return ($var === 1);
});
$newarray = array_filter($array);
Demo
$array = array(
'id' => 1,
'comp_id' => 1,
'transaction_purpose' => 0,
'source_of_funds' => 1,
'beneficiary_relationship' => 0,
'cus_occupation' => 0,
'cus_id_image_2' => 0,
'cus_id_image_3' => 0,
'ben_id_type' => 0,
'ben_id_number' => 1
);
$newarray = array_filter($array);
print_r($newarray);
Array
(
[id] => 1
[comp_id] => 1
[source_of_funds] => 1
[ben_id_number] => 1
)
Try this:
$returnArray = array_filter($result);
You can see PHP's array_filter function for more info.
Well, what else are you expecting to happen?
array_push($returnArray, $mainArray);
If you find an element which has >0 value, you push the ENTIRE original array onto the new one, not just the key/value you just tested.
You probably want:
$newarr = array();
foreach($mainArray as $key => $value) {
if ($value > 0) {
$newarr[$key] = $value;
}
}

Cannot modify multidimensional array PHP

I have two arrays.
First one ($dcel) looks like this:
Array(
[1] => Array
(
[V1] => 5
[V2] => 2
[F1] => 4
[F2] => 1
[P1] => 7
[P2] => 4
)
etc..
Second one ($PctOldNew) looks like this:
Array(
[0] => Array
(
[old] => 1
[new] => 3
)
etc..
I'm trying to find the 'old' values (which are the initial) in the first array. Here's my code:
foreach ($dcel as $latura) {
for($i = 0; $i <= $nrPct; $i++){
if($PctOldNew[$i]['old'] == $latura[V1]){
$latura[V1] = $PctOldNew[$i]['new'];
}
}
}
If I output the $PctOldNew inside if statment, the output it's the correct answer, but if i try to modify $latura[V1] the $dcel remains untouched.
I've tried with reference, keys... but nothing works and i can't see what's wrong.
This works:
edit: adding a 2nd array element to $dcel to show how it works
<?php
$dcel = Array(
'1' => Array
(
'V1' => 1, // <-- note that i changed this value from your original '5' to '1' so that your condition will actually match something, since this example data set doesn't actually have something to match
'V2' => 2,
'F1' => 4,
'F2' => 1,
'P1' => 7,
'P2' => 4
)
'2' => Array
(
'V1' => 5,
'V2' => 2,
'F1' => 4,
'F2' => 1,
'P1' => 7,
'P2' => 4
)
);
$PctOldNew = Array(
'0' => Array
(
'old' => 1,
'new' => 3
)
);
foreach ($dcel as &$latura) { // <-- reference on &$latura
for($i = 0; $i <= $nrPct; $i++){
if($PctOldNew[$i]['old'] == $latura['V1']){
$latura['V1'] = $PctOldNew[$i]['new'];
}
}
}
echo "<pre>";print_r($dcel);
output
Array
(
[1] => Array
(
[V1] => 3
[V2] => 2
[F1] => 4
[F2] => 1
[P1] => 7
[P2] => 4
)
[2] => Array
(
[V1] => 5
[V2] => 2
[F1] => 4
[F2] => 1
[P1] => 7
[P2] => 4
)
)
#CrayonViolent it didn't work, i tried so many times.
I was playing right now with the code and it seems that like this it's working:
foreach ($dcel as $key => $value) {
foreach ($value as $val) {
for($i = 0; $i <= $nrPct; $i++){
if($PctOldNew[$i]['old'] == $value[V1])
$new = $PctOldNew[$i]['new'];
}
$val = $new;
}
$dcel[$key][V1] = $val;
}
...but i don't know why.
The most convenient way in your case would be using array_map() function
Like this:
$array = array(1,2,3,4,5);
$replacements = array(
array('old'=>1, 'new'=>11),
array('old'=>3, 'new'=>33),
);
$array = array_map(function($element){
global $replacements;
foreach($replacements as $r) if($r['old']==$element) return $r['new'];
return $element;
}, $array);
print_r($array);
Result:
Array ( 11, 2, 33, 4, 5 )
Another weird way is to use array_walk
array_walk(&$dcel, function($latura){
for($i = 0; $i <= $nrPct; $i++){
if($PctOldNew[$i]['old'] == $latura[V1]){
$latura[V1] = $PctOldNew[$i]['new'];
}
}
});
Or array_map
$dcel = array_map(function($latura){
for($i = 0; $i <= $nrPct; $i++){
if($PctOldNew[$i]['old'] == $latura[V1]){
$latura[V1] = $PctOldNew[$i]['new'];
}
}
return $latura;
}, $dcel);
(Not sure why array_walk and array_map have reversed parameter position)
Updated with the real reason and 2 more possible solutions
The reason you can't modify $latura is because you are using for...each loop which will pass $latura by-value rather than by-reference. Based on this reason, you have 2 more solutions,
Use for $dcel as $key => $latura then you can change $dcel[$key]
Use for $dcel as &$latura then you can change the item directly

PHP - array values out and get similar values

I have an array like this
Array ( [item1] => pack1 [amount1] => 1 [price1] => 25 [amount2] => 1 [price2] => 45 [item3] => pack3 [amount3] => 4 [price3] => 65 [sender] => Submit )
I need to get the values item1 & item3 out of the array, then remove the item on them with a
str_replace
Then find largest number with
max
just the first part that is the toughest, any ideas?
foreach through the array, if the key contains item then get/set the values. Also check the value to see if it's greater than the previous to get the max
$a = array( "item1" => "pack1", "amount1" => 1, "price1" => 25, "amount2" => 1, "price2" => 45, "item3" => "pack3");
$b = array();
$pattern = '/item[1-9]/';
$max_index = 0;
foreach($a as $key => $value){
if(preg_match($pattern, $key, $matches, PREG_OFFSET_CAPTURE)){
$index = str_replace("item","",$key);
$b[$index] = $value;
if($index > $max_index){
$max_index = $index;
}
}
}
$max_value = $b[$max_index];
echo $max_value;

Categories