I have the following:
$array = array(1,2,3,4,5,6);
I need to "pivot" it to get :
Array ( [0] => 1 [1] => 4 [2] => 2 [3] => 5 [4] => 3 [5] => 6 )
by "pivot" I mean, let's imagine that the array is stored a 2 x 3 matrix (2 rows, and 3 columns). My goal is to pivot it, so that the matrix is now a 3 x 2 matrix (3 rows, 2 columns)
for that of course I need an extra argument, let's say "number of rows" (in this case this is like 2 rows)
I did the following:
function pivotArray($array, $nbrRows)
{
$countTotal = count($array);
$countCols = $countTotal / $nbrRows;
$chunk = array_chunk($array,$countCols);
$out = array();
for ($row=0;$row<$nbrRows;$row++) {
for ($col=0;$col<$countCols;$col++) {
$out[$col][$row] = $chunk[$row][$col];
}
}
$arraySingle = call_user_func_array('array_merge', $out);
return $arraySingle;
}
it works as designed but I wonder whether there is a better way to do that ? for instance avoiding the 2 for loops ? and also avoid the array_merge ?
Instead of reporcessing the array a few times, this code builds an intermediate array and spreads the elements based on $position % $countCols. I've also introduced ceil() to the count of columns in case there is an odd number of elements...
function pivotArray($array, $nbrRows)
{
$countTotal = count($array);
$countCols = ceil($countTotal / $nbrRows);
$arraySingle = [];
foreach ( $array as $position => $value ) {
$arraySingle[$position % $countCols][] = $value;
}
return array_merge(...$arraySingle);
}
I want to get the IDs which are in first column of CSV file according to the values in second column having same data.
I mean if code is EF in csv then its IDs value should get 1,2,3,4,5 and so on for other codes.
SO i took all code values in string adn explode it in array a dn tried to get the ids with matching code values but not succeeded. Please help
CSV file:
1,EF,Total Amount Invested,1190000,600000,360000,120000,
2,EF,Market Value,2457939,852578,453191,132471,2019/12/31
3,EF,Returns (Annualised),14.01,14.03,15.54,19.8,
4,EF,Benchmark Returns (Annualised),11.48,11.51,11.38,14.05,
5,EF,Additional Benchmark Returns (Annualised),12.23,12.75,13.42,16.28,
6,AF,Total Amount Invested,910000,600000,360000,120000,
7,AF,Market Value,1636525,845919,434171,132677,2019/12/31
8,AF,Returns (Annualised),15.13,13.71,12.56,20.14,
9,AF,Benchmark Returns (Annualised),11.94,11.51,11.38,14.05,
10,AF,Additional Benchmark Returns (Annualised),12.31,10.57,9.2,12.48,
My Code:
$fileName_sip = '/var/www/html/php/csv/file.csv';
$file_sip = fopen($fileName_sip, "r");
fseek($file_sip, 1, SEEK_CUR);
$sc_str = "EF,CF,TA,TS,BD,EF,ST,IS,TP,AG,MC,DB,CM,IF,CO,AF,O,EA,ES,CG,GO,NE,DE,ML,WF,EH,US,SC,OG,MM,ON,NI,RA,RC,RD";
$sc_arr = explode(',', $sc_str);
//echo "<pre>";print_r($sc_arr);die;
$i=0;
$ids =array();
for ($i=0; $i < count($sc_arr); $i++) {
while (($col_sip[] = fgetcsv($file_sip, 10000, ",")) !== FALSE) {
if ($col_sip[1] == $sc_arr[$i]) {
$ids[$i] = $col_sip[0];
}
}
}
echo "<pre>";print_r($ids);
I want ouput to be:
EF - 1,2,3,4,5
AF 6,7,8,9,10
Here is a simplified version which uses in_array() to check for the correct code value and then just builds 2 sub arrays in the $ids array using the code as the key.
Then it is just a case of presentation of the data, so just loop over the array you have created and generate the output in whatever format you like.
$file_sip = fopen($fileName_sip, "r");
$sc_str = "EF,CF,TA,TS,BD,EF,ST,IS,TP,AG,MC,DB,CM,IF,CO,AF,O,EA,ES,CG,GO,NE,DE,ML,WF,EH,US,SC,OG,MM,ON,NI,RA,RC,RD";
$sc_arr = explode(',', $sc_str);
$ids = [];
while (($row = fgetcsv($file_sip, 10000, ",")) !== FALSE) {
if (in_array($row[1], $sc_arr)) {
$ids[$row[1]][] = $row[0];
}
}
print_r($ids);
// make into a string
foreach ($ids as $key => $id){
echo $key . ' - ' . implode(',', $id) . PHP_EOL;
}
The first loop creates the $ids array like this
Array
(
[EF] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
[AF] => Array
(
[0] => 6
[1] => 7
[2] => 8
[3] => 9
[4] => 10
)
)
And the second outputs the results, but you can change that to suit your actual needs.
EF - 1,2,3,4,5
AF - 6,7,8,9,10
I'am searching the best way to do that test in php :
So i have a list which contains numbers and I have to check the succesion of these numbers so if there is no succession it is necessary to announce an alert and to recover the missing index or the list of the missing indexes
So for example my array is like that:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 6 [5] => 9 )
Here my algorithm must returns missing indexes are : [5,7,8]
If you make a range of the min and max value then use array_diff that should give you the result you want.
$arr = []; // your array
$range = range(min($arr), max($arr));
var_export(array_diff($range, $arr));
// [5,7,8]
https://3v4l.org/0pE3o
If you sort the numbers
sort($numbers);
You can use a nested loop.
foreach ($numbers as $k => $x) {
for ($n = $x + 1, $y = $numbers[$k + 1] ?? $x; $n < $y; $n++) {
$missing[] = $n;
}
}
The outer loop iterates the set of numbers, and the inner loop counts up from the current number to the next number.
I would like to split an array into three array that have similar sums - as close as possible
I have array
$arr = [1,2,4,7,1,6,2,8];
Desire output for example:
a = 8,2 // as sum is 10
b = 7,2,1 // as sum is 10
c = 6,4,1 // as sum is 10
Thanks
You can use the following algorithm:
Sort the input array from big to small
Create output array
for each element in the input - insert to the lowest sum in the output array.
Consider the following code:
$arr = [1,2,4,7,1,6,2,8];
sort($arr);
$arr = array_reverse($arr); // big to small
$out = array(array(),array(),array()); // output array
for($i = 0; $i < 8; $i++) {
$sums = array_map("array_sum" ,$out); // get all current sums of the array
$index = array_keys($sums, min($sums))[0]; // get the min sum
$out[$index][] = $arr[$i]; // add the element to the array with the lowest sum
}
echo print_r($out, true);
Now you will get:
array:
[0]: array:
[0] => 8
[1] => 2
[2] => 1
[1]: array:
[0] => 7
[1] => 2
[2] => 1
[2]: array:
[0] => 6
[1] => 4
Let's say we have arrays like below.
$arr00 = [0,1,2,...,9]; // It includes 9 arrays. So the score should be 9.
$arr01 = [0,1,...,8]; // score = 8
...
$arr09 = [0]; // score = 0
ArrScore (definition): If an array include an array with all elements it
gets one point. So in this case $arr00's total score is 9. Because it
includes all other 9 arrays. And $arr09's score will be 0.
Actual Conditions
Our array elements could be random numbers. (not sequent orders ascending +1)
There could be thousands of arrays.
Our arrays are always flat. (no duplicated element in an array)
We are using php (any theoretical approach is also ok)
Think that you have a standard PC and you will order these arrays everyday once. (No need for the result of "which arr eats which ones". Just ArrScores.)
Goal is to order arrays by ArrScore. And we need ArrScores. What should be the approach? (Theoretical or practical)
If I understood right, this might help:
function compare($a,$b) {
if(count(array_intersect($a, $b)) == count($a)) return -1;
else return 1;
}
$arr0 = [0,2,4,7];
$arr1 = [7,0,2,9,4];
$arr2 = [4,2];
$arr = [$arr0,$arr1,$arr2];
usort($arr,"compare");
foreach($arr as $a) {
print_r($a);
}
prints:
Array ( [0] => 4 [1] => 2 ) Array ( [0] => 0 [1] => 2 [2] => 4 [3] => 7 ) Array ( [0] => 7 [1] => 0 [2] => 2 [3] => 9 [4] => 4 )
EDIT:
Compute the ArrayScore for each array:
$arr0 = [0,2,4,7];
$arr1 = [7,0,2,9,4];
$arr2 = [4,2];
$arr = [$arr0,$arr1,$arr2];
$arrayScores = [];
//initialize the Scores with 0
foreach($arr as $a){
$arrayScores[] = 0;
}
//run through all arrays
for($i=0;$i<count($arr);$i++){
//with $j=$i+1, every combination is only checked once
for($j=$i+1; $j<count($arr);$j++){
if(count(array_intersect($arr[$j], $arr[$i])) == count($arr[$j])) {
$arrayScores[$i]++;
}
if(count(array_intersect($arr[$i], $arr[$j])) == count($arr[$i])){
$arrayScores[$j]++;
}
}
}