how to sorting multi array by value ?
i have data like this
$num_a = $_POST['num_a']; //get the value data by array num_a[]
$num_b = $_POST['num_b']; //get the value data by array num_b[]
$score = $_POST['score']; //get the value data by array socre[]
for ($i=0; $i < count($num_a); $i++) {
//set total data num_a and num_b with value from score
$ring[($num_a[$i])][($num_b[$i])] = $score[$i];
}
print_r($ring);
//output
Array
(
[0] => Array
(
[1] => 5
)
[1] => Array
(
[2] => 1
)
[2] => Array
(
[0] => 3
)
)
how to display the results sorted by desc, so the results are like this, thank you
the output i want
print_r($ring);
Array
(
[0] => Array
(
[1] => 5
)
[2] => Array
(
[0] => 3
)
[1] => Array
(
[2] => 1
)
)
Try this
$data = [
0 => [ 1 => 5],
1 => [ 2 => 1],
2 => [ 0 => 3],
];
uasort($data, function($a, $b) {
$a = array_pop($a);
$b = array_pop($b);
if ($a == $b)
{
return 0;
}
return ($a < $b) ? 1 : -1;
});
var_dump($data);
You can also use array_multisort (PHP 4, PHP 5)
array_multisort(
array_map(function($_){return reset($_);},$ring),
SORT_DESC,
$ring
);
Test
[akshay#localhost tmp]$ cat test.php
<?php
$data = array(
array( 1 => 5),
array( 2 => 1),
array( 0 => 3),
);
// Input
print_r($data);
// Sort DESC
array_multisort(array_map(function($_){return reset($_);},$data), SORT_DESC, $data);
// Output - sorted array
print_r($data);
?>
Output
[akshay#localhost tmp]$ php test.php
Array
(
[0] => Array
(
[1] => 5
)
[1] => Array
(
[2] => 1
)
[2] => Array
(
[0] => 3
)
)
Array
(
[0] => Array
(
[1] => 5
)
[1] => Array
(
[0] => 3
)
[2] => Array
(
[2] => 1
)
)
Related
I need to count consecutive repeated elements in the array, but if they are non consecutive I want to count them also, to have them in the same sequence as they are.
For example I have flowing array:
$array = Array('a', 'b', 'a', 'a', 'a', 'c', 'c', 'b', 'b', 'a', 'a', 'a', 'a');
if I use array_count_values function
example:
print_r(array_count_values($array));
Output will be:
Array ( [a] => 8 [b] => 3 [c] => 2 )
But I need to get output like this:
element counted value
a 1
b 1
a 3
c 2
b 2
a 4
You can iterate over the array, counting values while they are the same, and pushing a value to the result array when they are different:
$result = [];
$count = 0;
$current = $array[0];
for ($i = 0; $i < count($array); $i++) {
if ($array[$i] == $current) {
$count++;
}
else {
$result[] = array($current, $count);
$count = 1;
}
$current = $array[$i];
}
$result[] = array($current, $count);
print_r($result);
Output:
Array
(
[0] => Array
(
[0] => a
[1] => 1
)
[1] => Array
(
[0] => b
[1] => 1
)
[2] => Array
(
[0] => a
[1] => 3
)
[3] => Array
(
[0] => c
[1] => 2
)
[4] => Array
(
[0] => b
[1] => 2
)
[5] => Array
(
[0] => a
[1] => 4
)
)
Demo on 3v4l.org
Starting with an array with the first item from the source (and a count of 1), this then starts from the second item and checks if it matches the one in the current output. Adding 1 if it matches or adding a new entry if it doesn't...
$array = Array ('a','b','a','a','a','c','c','b','b','a','a','a','a');
$output = [ ["element" => $array[0], "count" => 1 ] ];
$outputPoint = 0;
for ( $i = 1, $count = count($array); $i < $count; $i++ ) {
if ( $array[$i] == $output[$outputPoint]["element"] ) {
$output[$outputPoint]["count"]++;
}
else {
$output[++$outputPoint] = ["element" => $array[$i], "count" => 1 ];
}
}
print_r($output);
Which outputs...
Array
(
[0] => Array
(
[element] => a
[count] => 1
)
[1] => Array
(
[element] => b
[count] => 1
)
[2] => Array
(
[element] => a
[count] => 3
)
[3] => Array
(
[element] => c
[count] => 2
)
[4] => Array
(
[element] => b
[count] => 2
)
[5] => Array
(
[element] => a
[count] => 4
)
)
This loops through the array and increments the number of elements in $count.
$array = ['a','b','a','a','a','c','c','b','b','a','a','a','a'];
$count = [];
$crt = -1;
foreach($array ?? [] as $element) {
if($crt == -1 || $count[$crt]["element"] != $element) {
$count[++$crt] = ["element" => $element, "counted_value" => 1];
} else {
$count[$crt]["counted_value"]++;
}
}
The array looks like:
Array
(
[0] => Array
(
[element] => a
[counted_value] => 1
)
[1] => Array
(
[element] => b
[counted_value] => 1
)
[2] => Array
(
[element] => a
[counted_value] => 3
)
[3] => Array
(
[element] => c
[counted_value] => 2
)
[4] => Array
(
[element] => b
[counted_value] => 2
)
[5] => Array
(
[element] => a
[counted_value] => 4
)
)
Compare 2 elements by iterating the array, if both the elements are the same, increase the count else keep the count as 1
$index = 0;
$finalArr[$index] = array('ele'=>$array[0],'cnt'=>1);
for($i=1; $i<count($array); $i++)
{
if($array[$i]===$array[$i-1])
{
++$finalArr[$index]['cnt'];
}
else
{
$finalArr[++$index] = array('ele'=>$array[$i],'cnt'=>1);
}
}
print_r($finalArr);
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 10 months ago.
I have two arrays:
Array
(
[0] => 5
[1] => 4
)
Array
(
[0] => BMW
[1] => Ferrari
)
And I would like to have that result. Merge the values with the same key
Array
(
[0] => Array
(
[0] => 5
[1] => BMW
)
[1] => Array
(
[0] => 4
[1] => Ferrari
)
)
How could I do that? Is there any native PHP function that does this? I tried array_merge_recursive and array_merge but did not get the expected result
As to #splash58 comment:
You can use array-map. Here an example:
$array = [["5", "4"], ["BMW", "Ferrari"]];
$res = array_map(null, ...$array);
Now res will contain:
Array
(
[0] => Array
(
[0] => 5
[1] => BMW
)
[1] => Array
(
[0] => 4
[1] => Ferrari
)
)
If the array in 2 different var you can use:
$res= array_map(null, ["5", "4"], ["BMW", "Ferrari"]);
<?php
$a = array();
$a[0] = '5';
$a[1] = '4';
$b = array();
$b[0] = 'BMW';
$b[1] = 'Ferrari';
merge_by_key($a, $b);
function merge_by_key($a, $b){
$c = array();
fill_array($c,$a);
fill_array($c,$b);
print_r($c);
}
function fill_array(&$c, $a) {
foreach ($a as $key => $value){
if(isset($c[$key])) {
array_push($c[$key], $value);
} else {
$c[$key] = array($value);
}
}
}
Output:
Array
(
[0] => Array
(
[0] => 5
[1] => BMW
)
[1] => Array
(
[0] => 4
[1] => Ferrari
)
)
You can use array_map with null as the first argument (there is an example in the manual), to get your desired result:
<?php
$nums = [0 => 5, 1 => 4];
$cars = [0 => 'BMW', 1 => 'Ferrari'];
var_export(array_map(null, $nums, $cars));
Output:
array (
0 =>
array (
0 => 5,
1 => 'BMW',
),
1 =>
array (
0 => 4,
1 => 'Ferrari',
),
)
Note that the following input would give the same result:
$nums = ['puff' => 5, 'powder' => 4];
$cars = ['powder' => 'BMW', 'puff' => 'Ferrari'];
It is the order, not the keys, that determine the pairings in the result when using array_map as above.
To associate by key using foreach (note order of $cars):
<?php
$nums = [0 => 5, 1 => 4];
$cars = [1 => 'Ferrari', 0 => 'BMW'];
foreach($nums as $k => $num)
$result[] = [$num, $cars[$k]];
var_export($result);
Results also in the desired output.
I have on array of data in below.
Array
(
[0] => Array
(
[0] => Array
(
[rating] => 4
[review] => nice
)
[1] => Array
(
[rating] => 2
[review] => good
)
)
)
We customize above array and need to my custom array .
Need out put like below array. array always need 5 to 1 key because i am using this array for rating & review functionality.
Array
(
[0] => Array
(
[5] => Array
(
[rating] => 0
[review] => ""
)
[4] => Array
(
[rating] => 4
[review] => nice
)
[3] => Array
(
[rating] => 0
[review] => ""
)
[2] => Array
(
[rating] => 2
[review] => "good"
)
[1] => Array
(
[rating] => 0
[review] => ""
)
)
)
I managed to self-solve. Please find below solution as per output.
$arr1 = array(array("rating"=>4,"review"=>"nice"),array("rating"=>2,"review"=>"good"));
$final =a rray();
for ($i=5; $i>=1; $i--) {
foreach ($arr1 as $key =>$val) {
if ($val['rating']==$i) {
$final[$i] = array("rating"=>$val['rating'],"review"=>$val['review']);
break;
} else {
$final[$i] = array("rating"=>0,"review"=>"");
}
}
}
print_r($final);
Iterate each top level array (if you don't have multiple top level arrays, then you should consider restructuring your array structure to be more concise)
call array_column() on the level2 array so that the rating values are assigned as keys for their respective subarray.
Iterate in descending order from 5 to 1 while conditionally saving data to the output array.
Code: (Demo)
$input = [
[
['rating' => 4, 'review' => 'nice'],
['rating' => 2, 'review' => 'good']
]
];
foreach ($input as $x => $level2) {
$keyed = array_column($level2, null, 'rating'); // setup more efficient lookup
for($i = 5 ; $i > 0 ; --$i) {
$result[$x][$i] = isset($keyed[$i]) ? $keyed[$i] : ['rating' => 0, 'review' => ''];
}
}
var_export($result);
// output is as desired
I have an array of records I want to create a separate array of skills and want to remove duplicate values, unset not providing desired result somehow, I am not able to find out what's wrong. For example I have record (a) in first skills array at index 0 and I have same record in last skills array at index 1 , I just want to remove any duplicate records but unset removing other records also.
$x = 0;
$y = 0;
$z = 0;
$data = array();
$all_data = array ( 0 => array ( "fname" => "Ann", "skills" => array ( 0 => "a", 1 => "b" )),
1 => array ( "fname" => "Bxx", "skills" => array ( 0 => "c", 1 => "d" )),
2 => array ( "fname" => "Sdd", "skills" => array ( 0 => "e", 1 => "a" ))
);
while( $x < count($all_data)){
while($y < count($all_data[$x]['skills'])){
$data[$x] = $all_data[$x]['skills'];
if (in_array($data[$x][$y], $data[$x])){
unset($data[$x][$y]);
}
$y++;
}
$y = 0;
$x++;
}
The result I am getting is this
Array
(
[0] => Array
(
[0] => a
)
[1] => Array
(
[0] => c
)
[2] => Array
(
[0] => e
[1] => a
)
)
I am expecting
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => c
[1] => d
)
[2] => Array
(
[0] => e
)
)
You could try something like this :
$keys=[];
foreach ($all_data as $index1 => $item) {
if (!isset($item['skills'])) continue;
foreach ($item['skills'] as $index2 => $value) {
if (!in_array($value, $keys)) {
$data[$index1][] = $value ;
$keys[] = $value ;
}
}
}
unset($keys);
print_r($data);
Outputs :
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => c
[1] => d
)
[2] => Array
(
[0] => e
)
)
I have array A and B with the structure:
A:
Array
(
[0] => 2013-08-01
[1] => 2013-08-02
[2] => 2013-08-03
[3] => 2013-08-04
)
and B:
Array
(
[0] => Array
(
[0] => 2013-08-01
[1] => 2
[2] => 0
[3] => 0
)
[1] => Array
(
[0] => 2013-08-02
[1] => 0
[2] => 4
[3] => 0
)
[2] => Array
(
[0] => 2013-08-04
[1] => 0
[2] => 1
[3] => 0
)
)
The question is I want to combine twi ARRAY (A & B) to be like this:
Array
(
[0] => Array
(
[0] => 2013-08-01
[1] => 2
[2] => 0
[3] => 0
)
[1] => Array
(
[0] => 2013-08-02
[1] => 0
[2] => 4
[3] => 0
)
[2] => Array
(
[0] => 2013-08-03
[1] => 0
[2] => 0
[3] => 0
)
[3] => Array
(
[0] => 2013-08-04
[1] => 0
[2] => 1
[3] => 0
)
)
How to merge the both of array?
function combine($a, $b) {
foreach($a as $item_a) {
foreach($b as $item_b) {
if(in_array($item_a, $item_b)) {
continue 2;
}
}
$b[] = array(
$item_a, 0, 0, 0
);
}
usort($b, function($a, $b){return $a[0] > $b[0];});
return $b;
}
<?
$a = Array
(
"2013-08-01",
"2013-08-02",
"2013-08-03",
"2013-08-04"
);
$b = Array
(
Array (
"2013-08-01",
2,
0,
0
),
Array (
"2013-08-02",
0,
4,
0
),
Array (
"2013-08-04",
0,
1,
0
)
);
foreach ($a as $a_item) {
$found = FALSE;
foreach ($b as $b_item) {
if($b_item[0]==$a_item) {
$found = TRUE;
}
}
if(!$found) {
$b[] = Array (
$a_item,
0,
0,
0
);
}
}
print_r ($b);
?>
This should work if you don't have a huge amount of data in the arrays. If you have a large amount of data you should probably do some redesign to make it faster.
Assuming that the core dates are in array B, my approach would be to loop through array A and add to array B if a date is found that is not already in array B.
foreach ($arrA as $datecheck) {
$blnAdd = 1;
foreach ($arrB as $compare) {
if ($compare[0] == $datecheck) {
// If found, don't add!
$blnAdd = 0;
}
}
if ($blnAdd == 1) {
$arrB[] = array($datecheck, 0, 0, 0);
}
}
// When done, sort array B
// Create helper array for multisort
$arrHelper = array();
foreach ($arrB as $data) {
$arrHelper = $data[0];
}
// Then, sort array B using values from helper array
array_multisort($arrHelper, $arrB);
Then, $arrB should contain the values you need.