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];
}
}
Related
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 is a question for all the array specialists out there. I have an multi dimension array with a result as number (can be 0,1 or 2) and need the average for each grouped by parent.
In the example below the calculation would be:
subentry1_sub1 = 2 + 2 = 4 (4/2=2)
subentry1_sub2 = 1 + 1 = 2 (2/2=1)
So what I try to archive in PHP is the following result:
subentry1_sub1 average = 2
subentry1_sub2 average = 1
...
I already tried some solutions from similar questions. But with all the recursive functions I didn't managed to get it aggregated by the last child name (e.g. subentry1_sub1).
Any ideas?
EDIT:
subentry1_sub1 is 2 + 2 because its two times in the array
[entry1] => [subentry1] => [subentry1_sub1] => result
[entry2] => [subentry1] => [subentry1_sub1] => result
Array
(
[entry1] => Array
(
[subentry1] => Array
(
[subentry1_sub1] => Array
(
[value] => abc
[result] => 2
)
[subentry1_sub2] => Array
(
[value] => abc
[result] => 1
)
)
[subentry2] => Array
(
[subentry2_sub1] => Array
(
[value] => abc
[result] => 1
)
[subentry2_sub2] => Array
(
[value] => abc
[result] => 1
)
)
)
[entry2] => Array
(
[subentry1] => Array
(
[subentry1_sub1] => Array
(
[value] => abc
[result] => 2
)
[subentry1_sub2] => Array
(
[value] => abc
[result] => 1
)
)
[subentry2] => Array
(
[subentry2_sub1] => Array
(
[value] => abc
[result] => 1
)
[subentry2_sub2] => Array
(
[value] => abc
[result] => 1
)
)
)
)
Try this code. In this i have created a new array $sum which will add result value of same subentry childs with same key and another array $count which will count the number of times each key repeats
<?php
$data = array('entry1'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>2),
'subentry1_sub2'=>array('value'=>'abc','result'=>1)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>1),
'subentry2_sub2'=>array('value'=>'abc','result'=>1)
)
),
'entry2'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>2),
'subentry1_sub2'=>array('value'=>'abc','result'=>1)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>1),
'subentry2_sub2'=>array('value'=>'abc','result'=>1)
)
)
);
$sum = array();
$repeat = array();
foreach($data as $input){
foreach($input as $array){
foreach($array as $key=>$value){
if(array_key_exists($key,$sum)){
$repeat[$key] = $repeat[$key]+1;
$sum[$key] = $sum[$key] + $value['result'];
}else{
$repeat[$key] = 1;
$sum[$key] = $value['result'];
}}}}
echo "<pre>";
print_r($sum);
print_r($repeat);
foreach($sum as $key=>$value){
echo $key. ' Average = '. $value/$repeat[$key]."</br>";
}
Output
Array
(
[subentry1_sub1] => 4
[subentry1_sub2] => 2
[subentry2_sub1] => 2
[subentry2_sub2] => 2
)
Array
(
[subentry1_sub1] => 2
[subentry1_sub2] => 2
[subentry2_sub1] => 2
[subentry2_sub2] => 2
)
subentry1_sub1 Average = 2
subentry1_sub2 Average = 1
subentry2_sub1 Average = 1
subentry2_sub2 Average = 1
You can easily calculate avg now
Note : As you mentioned you are counting occurence of subentry1_sub1 etc so i did the same so it will also count whether key result exists or not
I know this is an old thread but im pretty sure there is a much easier way of doing this for anyone who is interested:
If you know the result will always be a number:
foreach($my_array as $entry_name => $entry_data)
{
foreach($entry_data as $sub_name => $sub_data)
{
$sub_results = array_column($sub_data, 'result');
$averages[$entry_name][$sub_name] = array_sum($sub_results)/count($sub_results);
}
}
If its possible the result could be NULL or empty, this will check it and return 'N/A' if there is no valid data to calculate an average from:
foreach($my_array as $entry_name => $entry_data)
{
foreach($entry_data as $sub_name => $sub_data)
{
$sub_results = array_filter(array_column($sub_data, 'result'));
$averages[$entry_name][$sub_name] = (count($sub_results) > 0 ? array_sum($sub_results)/count($sub_results) : 'N/A');
}
}
both of these solutions will give you an averages array that will output the average per subentry per entry.
Try this like,
<?php
$data=array('entry1'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>3),
'subentry1_sub2'=>array('value'=>'abc','result'=>3)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>2),
'subentry2_sub2'=>array('value'=>'abc','result'=>8)
)
),
'entry2'=>array(
'subentry1'=>
array(
'subentry1_sub1'=>array('value'=>'abc','result'=>6),
'subentry1_sub2'=>array('value'=>'abc','result'=>6)
),
'subentry2'=>
array(
'subentry2_sub1'=>array('value'=>'abc','result'=>10),
'subentry2_sub2'=>array('value'=>'abc','result'=>12)
)
)
);
foreach($data as $k=>$v){
echo "----------------$k---------------------\n";
if(is_array($v)){
foreach($v as $a=>$b){
if(is_array($b)){
echo $a.' average = ';
$c=array_keys($b);// now get *_sub*
$v1=isset($b[$c[0]]['result']) ? $b[$c[0]]['result'] : '';
$v2=isset($b[$c[1]]['result']) ? $b[$c[1]]['result'] : '';
echo ($v1+$v2)/2;
echo "\n";
}
}
}
}
Online Demo
In the meantime I found a simple working solution myself:
foreach ($data as $level2) {
foreach ($level2 as $level3) {
foreach ($level3 as $keyp => $level4) {
foreach ($level4 as $key => $value) {
if($key == 'result') $stats[$keyp] += $value;
}
}
}
}
With that you get the total for every key in an new array $stats.
But be sure to checkout the solution from user1234, too. It's working great and already includes the calculation of the average.
https://stackoverflow.com/a/39292593/2466703
I have an array of arrays set up like so. There are a total of 10 arrays but I will just display the first 2. The second column has a unique id of between 1-10 (each only used once).
Array
(
[0] => Array
(
[0] => User1
[1] => 5
)
[1] => Array
(
[0] => User2
[1] => 3
)
)
I have another array of arrays:
Array
(
[0] => Array
(
[0] => 3
[1] => 10.00
)
[1] => Array
(
[0] => 5
[1] => 47.00
)
)
where the first column is the id and the second column is the value I want to add to the first array.
Each id (1-10) is only used once. How would I go about adding the second column from Array#2 to Array#1 matching the ID#?
There are tons of ways to do this :) This is one of them, optimizing the second array for search and walking the first one:
Live example
<?
$first_array[0][] = 'User1';
$first_array[0][] = 5;
$first_array[1][] = 'User2';
$first_array[1][] = 3;
$secnd_array[0][] = 3;
$secnd_array[0][] = 10.00;
$secnd_array[1][] = 5;
$secnd_array[1][] = 47.00;
// Make the user_id the key of the array
foreach ($secnd_array as $sca) {
$searchable_second_array[ $sca[0] ] = $sca[1];
}
// Modify the original array
array_walk($first_array, function(&$a) use ($searchable_second_array) {
// Here we find the second element of the first array in the modified second array :p
$a[] = $searchable_second_array[ $a[1] ];
});
// print_r($first_array);
Assuming that 0 will always be the key of the array and 1 will always be the value you'd like to add, a simple foreach loop is all you need.
Where $initial is the first array you provided and $add is the second:
<?php
$initial = array(array("User1", 5),
array("User2", 3));
$add = array(
array(0, 10.00),
array(1, 47.00));
foreach ($add as $item) {
if (isset($initial[$item[0]])) {
$initial[$item[0]][] = $item[1];
}
}
printf("<pre>%s</pre>", print_r($arr1[$item[0]], true));
I don't know if I got you right, but I've come up with a solution XD
<?php
$array_1 = array(
0 => array(
0 => 'ID1',
1 => 5
),
1 => array(
0 => 'ID2',
1 => 3
)
);
$array_2 = array(
0 => array(
0 => 3,
1 => 10.00
),
1 => array(
0 => 5,
1 => 47.00
)
);
foreach($array_1 as $key_1 => $arr_1){
foreach($array_2 as $key_2 => $arr_2){
if($arr_2[0] == $arr_1[1]){
$array_1[$key_1][2] = $arr_2[1];
}
}
}
var_dump($array_1);
?>
Demo: https://eval.in/201648
The short version would look like this:
<?php
$array_1 = array(array('ID1',5),array('ID2',3));
$array_2 = array(array(3,10.00),array(5,47.00));
foreach($array_1 as $key => $arr_1){
foreach($array_2 as$arr_2){
if($arr_2[0] == $arr_1[1]){
$array_1[$key][2] = $arr_2[1];
}
}
}
var_dump($array_1);
?>
Demo: https://eval.in/201649
Hope that helps :)
A quick and dirty way just to show you one of the more self-explaining ways to do it :)
$users = array(
0 => array(
0 => 'User1',
1 => 123
),
1 => array(
0 => 'User2',
1 => 456
)
);
$items = array(
0 => array(
0 => 123,
1 => 'Stuff 1'
),
1 => array(
0 => 456,
1 => 'Stuff 2'
)
);
foreach($items as $item){
foreach($users as $key => $user){
if($item[0] == $user[1])
array_push($users[$key], $item[1]);
}
}
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
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;