Only 1 array (irregular array) - php

http://prntscr.com/fl69px
Hi, how can I get the part shown in the picture? There are many arrays.
Array
(
[max] => 46.784
[total] => 74.562
)
Array
(
[0] => 6
)
Array
(
[0] => 3
)
Array
(
[0] => 18 Oct 2017 14:12
)
Array
(
[0] => 2017-06-18T14:12:33+03:00
)
Array
(
[0] => New Cup
)
In short, I am not asking: New Cup
There are 16 in total.

Assuming that you want this array:
Array(
[bet] => 3
[featureEvent] => 0
[bank] => 0
[column] => 2
[requiredBet] => 2
)
You can create a basic php foreach-loop, which loops through your array and returns each key and value.
Currently we do not know how you created your array nor how the array name is, but lets assume that the array's name above is $bets
The foreach loop would look like this then:
foreach($bets as $betKey => $betValue)
{
// do something ...
// echo the values
echo $betValues;
}

Related

Sorting multiple subarrays based on a total count from all sub arrays

I have some data which looks like this (reduced)
Array
(
[datasets] => Array
(
[0] => Array
(
[label] => NEW
[backgroundColor] => #37fdfd
[data] => Array
(
[0] => 0
[1] => 0
[2] => 5
[3] => 0
)
)
[1] => Array
(
[label] => Grade A
[backgroundColor] => #76ef76
[data] => Array
(
[0] => 8
[1] => 12
[2] => 11
[3] => 0
)
)
[2] => Array
(
[label] => Grade B
[backgroundColor] => #f9f96d
[data] => Array
(
[0] => 1
[1] => 6
[2] => 5
[3] => 3
)
)
[3] => Array
(
[label] => Grade C
[backgroundColor] => #f3ca36
[data] => Array
(
[0] => 3
[1] => 0
[2] => 1
[3] => 4
)
)
[4] => Array
(
[label] => Grade D
[backgroundColor] => #f3ca36
[data] => Array
(
[0] => 3
[1] => 0
[2] => 1
[3] => 0
)
)
)
[labels] => Array
(
[0] => User 0
[1] => User 1
[2] => User 2
[3] => User 3
)
)
Here is a JSON string of the data (not reduced, numbers may differ slightly)
{"datasets":[{"label":"NEW","backgroundColor":"#37fdfd","data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},{"label":"Grade A","backgroundColor":"#76ef76","data":[9,14,12,0,4,17,13,0,10,0,18,18,12,13,13,4]},{"label":"Grade B","backgroundColor":"#f9f96d","data":[1,6,5,0,6,5,2,0,1,0,2,1,4,3,1,15]},{"label":"Grade C","backgroundColor":"#f3ca36","data":[3,0,1,0,2,0,0,0,0,0,1,1,0,0,0,0]},{"label":"Grade C","backgroundColor":"#f3ca36","data":[3,0,1,0,2,0,0,0,0,0,1,1,0,0,0,0]}],"labels":["User 0","User 1","User 2","User 3","User 4","User 5","User 6","User 7","User 8","User 9","User 10","User 11","User 12","User 13","User 14","User 15"]}
Each dataset has an array of data which has keys that directly relates to a key in the labels array. This is currently sorted in alphabetical order by the label.
This data structure is the structure required for Chart.js, which I am using to display a stacked bar chart on my webpage.
Essentially what I need to accomplish is to sort the data array for every user in the labels array based on the sum of each data set for that user. I also need to sort the labels array to be in the same order.
My original idea on how to achieve this is to create a temporary array, loop through all the data sets and add them to this temporary array in the order necessary, but I got stuck after calculating the total for each user. Here is my attempt:
$return = [];
foreach($calculated['labels'] as $key => &$name) {
$total = 0;
foreach($calculated['datasets'] as $dataset) {
$total += $dataset['data'][$key];
}
echo "$name - $total<br>";
}
How can I sort my data and labels in descending order based on the total for each user from all datasets.
Here is my expected output for the reduced data above
Array
(
[datasets] => Array
(
[0] => Array
(
[label] => NEW
[backgroundColor] => #37fdfd
[data] => Array
(
[2] => 5
[1] => 0
[0] => 0
[3] => 0
)
)
[1] => Array
(
[label] => Grade A
[backgroundColor] => #76ef76
[data] => Array
(
[2] => 11
[1] => 12
[0] => 8
[3] => 0
)
)
[2] => Array
(
[label] => Grade B
[backgroundColor] => #f9f96d
[data] => Array
(
[2] => 5
[1] => 6
[0] => 1
[3] => 3
)
)
[3] => Array
(
[label] => Grade C
[backgroundColor] => #f3ca36
[data] => Array
(
[2] => 1
[1] => 0
[0] => 3
[3] => 4
)
)
[4] => Array
(
[label] => Grade D
[backgroundColor] => #f3ca36
[data] => Array
(
[2] => 1
[1] => 0
[0] => 3
[3] => 0
)
)
)
[labels] => Array
(
[2] => User 2 //23 total across all data sets
[1] => User 1 //18 total across all data sets
[0] => User 0 //15 total across all data sets
[3] => User 3 //7 total across all data sets
)
)
The key in the labels array acts as a unique identifier for each user in each dataset data array.
Notice how each set of data inside of each dataset is in the same order, as is the labels array. Each set should be ordered by the total amount from all sets for each user, not necessarily the highest number in each dataset.
For clarification, each set of data in each dataset contains a list of values, the key for each value is directly related to the key for each user in the labels array. So in my example, we have User 0 who has the key "0". This user has a total of 23 from adding up the values from each dataset with the key "0".
Complete solution:
// get array
$a = json_decode('{"datasets":[{"label":"NEW","backgroundColor":"#37fdfd","data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},{"label":"Grade A","backgroundColor":"#76ef76","data":[9,14,12,0,4,17,13,0,10,0,18,18,12,13,13,4]},{"label":"Grade B","backgroundColor":"#f9f96d","data":[1,6,5,0,6,5,2,0,1,0,2,1,4,3,1,15]},{"label":"Grade C","backgroundColor":"#f3ca36","data":[3,0,1,0,2,0,0,0,0,0,1,1,0,0,0,0]},{"label":"Grade C","backgroundColor":"#f3ca36","data":[3,0,1,0,2,0,0,0,0,0,1,1,0,0,0,0]}],"labels":["User 0","User 1","User 2","User 3","User 4","User 5","User 6","User 7","User 8","User 9","User 10","User 11","User 12","User 13","User 14","User 15"]}', true);
// get array of arrays with `data` key from each data set
$users = array_column($a['datasets'], 'data');
// tricky code to sum arrays
$sums = array_map('array_sum', array_map(null, ...$users));
// sort array with keeping keys
arsort($sums);
// we need flip so as `array_replace` will work as expected
$keys = array_flip(array_keys($sums));
// "sorting" `data` subarrays
foreach ($a['datasets'] as &$item) {
$item['data'] = array_replace($keys, $item['data']);
}
// "sorting" `labels` subarray
$a['labels'] = array_replace($keys, $a['labels']);
// see the result
print_r($a);
Fiddle here https://3v4l.org/a7rPL
I see this task as a perfect candidate for array_multisort(). Your synchronously sorted subarrays don't need to retain their initial keys like in u_mulder's output.
The first parameter must be the array of columnar sums, then the descending sort flag as the second parameter, then the labels subarray as a reference, then the dynamic number of data subarrays as references to the original array.
Code: (Demo)
$params = [[], SORT_DESC, &$array['labels']];
foreach ($array['datasets'] as ['data' => &$data]) {
foreach ($data as $i => $d) {
$params[0][$i] = ($params[0][$i] ?? 0) + $d;
}
$params[] = &$data;
}
array_multisort(...$params);
var_export($array);
This looks like a typical job for map(reduce).sort: map each element to an object with id, so you can preserve "which user this used to be" information, and total, the result of reducing data. Then sort with a custom sort function (a,b) => a.total - b.total.
E.g.
function map_total($user, $pos) {
return array(
"id" => $pos,
"total" => array_sum($user.data)
);
}
function cmp_total($a, $b) {
return $a["total"] - $b["total"];
}
$mapped = array_map("map_total", $thing.dataset, array_keys($thing.dataset));
$sorted = usort($mapped, "cmp_total");

array unique make item disapear

I have this array :
Array
(
[0] => Array
(
[0] => Array
(
[0] => 10
[id_list] => 1
[id] => 1
)
[1] => Array
(
[0] => 11
[id_list] => 1
[id] => 1
)
[2] => Array
(
[0] => 12
[id_list] => 1
[id] => 1
)
)
[1] => Array
(
[0] => Array
(
[0] => 11
[id_list] => 2
[id] => 2
)
[1] => Array
(
[0] => 12
[id_list] => 2
[id] => 2
)
)
[2] => Array
(
[0] => Array
(
[0] => 13
[id_list] => 4
[id] => 4
)
)
)
and this code (where $dataListe is the result of a fetchAll query) :
$result = [];
foreach($dataListe as $listeDiff){
$result[] = $listeDiff;
}
// $resultUnique = array_unique($result);
echo "<pre>".print_r($result, true)."</pre>";
as you can see, there's some contact similar in my first and my second array (but contact can be the same in the 1st and the 3rd array, is I choose to add my contact in my 3rd array).
I want to remove the duplicate of each element in the general array.
But when I use array unique, I get this result :
Array
(
[0] => Array
(
[0] => Array
(
[0] => 10
[id_list] => 1
[id] => 1
)
[1] => Array
(
[0] => 11
[id_list] => 1
[id] => 1
)
[2] => Array
(
[0] => 12
[id_list] => 1
[id] => 1
)
)
)
Please I need help to only keep 1 item of each array at the end !
EDIT : I have almost the good result with the code below, but the id 12 is missing
$result = [];
foreach($dataListe as $listeDiff){
foreach($listeDiff as $contact){
if(!in_array($contact,$result)){
$result[] = $contact;
}
break;
}
}
As the PHP docs says :
Note: Note that array_unique() is not intended to work on multi dimensional arrays. (http://php.net/manual/en/function.array-unique.php)
You can try this solution
$uniqueResult = array_map("unserialize", array_unique(
array_map("serialize", $result)
));
as suggested by #daveilers on this question How to remove duplicate values from a multi-dimensional array in PHP.

Rename multidimensional array keys

I'm trying to rename my keys in a multidimensional array. I looked at this: Renaming the keys in multidimensional associate arrays and it does rename it, but only for 1 of my 2 arrays. How can I get it to rename the 1st array time and the second array count?
My output right now is :
Array
(
[0] => Array
(
[0] => 00:00
[1] => 00:15
[2] => 00:30
)
[1] => Array
(
[0] => 8
[1] => 9
[2] => 8
)
)
I need [0] to be time and [1] to be count.
If I use this:
foreach ($sliced_array as $id => $dataset) {
$newArray["time"] = $dataset;
}
I can get it to output only array [1] renamed as time. It should be count and array [0] disappears entirely. Is there a way to focus which dataset the foreach targets? dataset[0] does not work.
My expected output is:
Array
(
[time] => Array
(
[0] => 00:00
[1] => 00:15
[2] => 00:30
)
[count] => Array
(
[0] => 8
[1] => 9
[2] => 8
)
)
Did you just try:
$myArray["time"] = $myArray[0];
$myArray["count"] = $myArray[1];
unset($myArray[0]);
unset($myArray[1]);
or just:
$newArray["time"] = $myArray[0];
$newArray["count"] = $myArray[1];
?
$newArray = array_combine(array('time','count'),$sliced_array);
http://es1.php.net/array_combine

What does [1] => 0 mean in this array?

I know this must be a fairly simple question, but I haven't managed to stumble across an answer yet.
I have the following array
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
When I use print_r($qid) I get the following
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
I don't understand [1] => 0
in
[0] => Array ( [0] => 1 [1] => 0 )
If someone could explain what [1] => 0 means in this array, I'd greatly appreciate it. Thanks.
EDIT: It turns out that my array was indeed different to what I had written above, because it had been modified later in the code. Thanks everyone for the great answers. I'm still reading over them all and trying to make my mind understand them (Arrays turn my mind to jello).
[1] => 0 denotes an array element with the value 0.
The numbers in [] are array keys. So [1] is the second element of a numerically indexed array, (which starts with [0]), and the value of the second element ([1]) is 0.
PHP uses => as an operator to relate array keys/indices to their values.
So an overall explanation of this structure:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
The outer array is a numerically indexed array, and each of its elements is a sub-array. The first of them ([0]) is an array containing 2 elements, while the rest of them ([1] through [3]) are arrays containing only one single element.
That two-dimensional array is actually a one-dimensional array of arrays, which is why you're getting the nesting. The [x] => y bit simply means that index x of the array has the value y.
Now your output in this case doesn't actually match your code, since
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
produces:
Array (
[0] => Array ( [0] => 1 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
If you wanted to get:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
(with the first array having two elements), you'd actually need:
$qid[0][0]=1;
$qid[0][1]=0;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
You probably added a second item to $qid[0] somewhere ($qid[0][1] = 0). This code
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
outputs the the correct values for me (without [1] => 0:
Array ( [0] => Array ( [0] => 1 ) [1] => Array ( [0] => 2 ) [2] => Array ( [0] => 3 ) [3] => Array ( [0] => 4 ) )
It means that your index 0 in the original Array contains another Array of 2 items.
Specifically [1] => 0 means that the 2nd item of the "child" Array contains the number 0.
[1] => 0
in this simple way we can say that 1 is your array key and 0 is value for the 1 key
0 is store at the 1 key of the array
thanks
Simply put, you have a numerically indexed multidimensional array. http://php.net/manual/en/language.types.array.php should have all the information you need to read up on this.
As to why you have the [1] => 0, you'll need to look a little deeper into your code to see where it gets assigned.
I got the following result after printing out the array using print_r:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 2
)
[2] => Array
(
[0] => 3
)
[3] => Array
(
[0] => 4
)
)
I guess, you might have set a value for $gid[0][1] somewhere in your code.

Merge a 3D Array with 2D Array Based on Shared Values

I need to merge a three-dimensional array with a two-dimensional array based on a shared value for 'id.'
In the example below, "George Washington" has an 'id' of 1. I need to append his 'value', which is found in the second array where 'id' is also 1.
The 'id' of "John Adams" is 2, which is not found in the second array. As a result, his 'value' needs to be set to 0 (or NULL).
The final result is a three-dimension array where 'value' has been added to each item in the original array.
Array #1
Array
(
[0] => Array
(
[0] => Array
(
[id] => 1
[name] => "George Washington"
)
[total] => 8
[average] => 2.5
)
[1] => Array
(
[0] => Array
(
[id] => 2
[name] => "John Adams"
)
[total] => 6
[average] => 3.0
)
[2] => Array
(
[0] => Array
(
[id] => 5
[name] => "James Monroe"
)
[total] => 9
[average] => 2.0
)
)
Array #2
Array
(
[0] => Array
(
[id] => 1
[value] => 12
)
[1] => Array
(
[id] => 5
[value] => 18
)
)
Desired Result:
Array
(
[0] => Array
(
[0] => Array
(
[id] => 1
[name] => "George Washington"
)
[total] => 8
[average] => 2.5
[value] => 12
)
[1] => Array
(
[0] => Array
(
[id] => 2
[name] => "John Adams"
)
[total] => 6
[average] => 3.0
[value] => 0
)
[2] => Array
(
[0] => Array
(
[id] => 5
[name] => "James Monroe"
)
[total] => 9
[average] => 2.0
[value] => 18
)
)
What I've tried so far:
I separated all of the 'id' values from the first array into a new array named $ids. Then while looping through the items in the second array, I check to see whether the 'id' from the second array is found in the $ids array.
But then I'm stuck because I don't know how to specify which item in the first array needs to receive the new 'value'. Also, this seems like a messy solution because of the overhead involved in creating the $ids array.
Didn't even realize you had tried to list the IDs and such before I was done writing this, but here you go anyway. Good luck!
$array1_size = count($array1);
$array2_size = count($array2);
// Creates a list containing all available IDs of Array1
for ($i = 0; $i < $array1_size; $i ++) {
$id_list[] = $array1[$i][0]['id'];
$array1[$i]['value'] = NULL; // Adds a NULL to all value fields
}
// Loops through Array2
for ($i = 0; $i < $array2_size; $i++) {
if (in_array($array2[$i]['id'], $id_list)) { // Checks if each ID exists in the ID list
$key = array_search($array2[$i]['id'], $id_list); // Gets the key of the matching ID
$array1[$key]['value'] = $array2[$i]['value']; // Adds the value
}
}
Edit: Values are now set to NULL by default and thus only gets changed later on if needed.

Categories