Highlighting array values - php

I have an array of statistics on racing dogs. I need to highlight the maximum and minimum values in each element by adding another element. Let me explain.
Example of array
Array
(
[1] => Array
(
[fast_calc_7] => 31.06
[av_calc_7] => 25.03
)
[2] => Array
(
[fast_calc_7] => 16.74
[av_calc_7] => 18.06
)
[3] => Array
(
[fast_calc_7] => 30.93
[av_calc_7] => 31.06
)
[4] => Array
(
[fast_calc_7] => 29.01
[av_calc_7] => 25.08
)
[5] => Array
(
[fast_calc_7] => 30.72
[av_calc_7] => 31.02
)
[6] => Array
(
[fast_calc_7] => 31.16
[av_calc_7] => 36.02
)
)
Example of resulting array
I need to compare these values and add another element specifying if it is the highest of lowest value. For example, it should generate an array such as the following.
Array
(
[1] => Array
(
[fast_calc_7] => 31.06
[av_calc_7] => 25.03
)
[2] => Array
(
[fast_calc_7] => 16.74
[fast_calc_7_lowest] => TRUE
[av_calc_7] => 18.06
[av_calc_7_lowest] => TRUE
)
[3] => Array
(
[fast_calc_7] => 30.93
[av_calc_7] => 37.06
[av_calc_7_highest] => TRUE
)
[4] => Array
(
[fast_calc_7] => 29.01
[av_calc_7] => 25.08
)
[5] => Array
(
[fast_calc_7] => 30.72
[av_calc_7] => 31.02
)
[6] => Array
(
[fast_calc_7] => 31.16
[fast_calc_7_highest] => TRUE
[av_calc_7] => 36.02
)
)
I'm sure there is a really simple way to do this. The more I have to iterate through arrays, the slower my application gets!
Thanks guys.
EDIT: How data is sourced
JSON array gathered from greyhound website for each dogs "race history"
JSON array is processed to form a nice array for each dogs history with the data for example the time for each race, finishing position etc.
This data is then calculated for each dog to find the fastest time, average time and other data. This is the array above. (Each array is a different dog).
At this point, I need the array processed to add in the highlighting elements.

There isn't much to it. You need to loop over the array, maintaining variables with the indexes of the high/low elements so far for each attribute. After the loop, access those elements and add your extra data.
$lowAverage = $highAverage = array('index' => null, 'value' => 0);
$lowFast = $highFast = array('index' => null, 'value' => 0);
foreach($dogs as $index => $data) {
if($lowAverage['index'] == null || $data['av_calc_7'] < $lowAverage['value']) {
$lowAverage = array('index' => $index, 'value' => $data['av_calc_7']);
}
if($highAverage['index'] == null || $data['av_calc_7'] > $highAverage['value']) {
$highAverage = array('index' => $index, 'value' => $data['av_calc_7']);
}
// same for $lowFast, $highFast
}
if($lowAverage['index'] != null) {
$dogs[$lowAverage['index']]['av_calc_7_lowest'] = true;
}
// same for the other 3 values

Related

How to move array in multidimensional array using key value?

How to move array in multidimensional aray with key value?
I'm using array_push to add values to a multidimensional array. i have an array
$myArray = Array(Array('code' => '1','room' => Array('name' => 'Room-A')),Array('code' =>'1','room' => Array('name' => 'Room-B'
)), Array('code' => '2','room' => Array('name' => 'Vip-1')),Array('code' => '2','room' => Array('name' => 'Vip-2')));
i tried using code like this:
for ($i=0; $i <count($myArray) ; $i++) {
if ($myArray[$i]['code']=='1') {
array_push($myArray[$i]['room'], $myArray[$i]['room']);
}
else{
array_push($myArray[$i]['room'], $myArray[$i]['room']);
}
}
i want the result like this :
Array
(
[0] => Array
(
[code] => 1
[room] => Array
(
[0] => Array
(
[name] => Room-A
)
[1] => Array
(
[name] => Room-B
)
)
)
[1] => Array
(
[code] => 2
[room] => Array
(
[0] => Array
(
[name] => Vip-1
)
[1] => Array
(
[name] => Vip-2
)
)
)
)
Any idea how to join this array?
You can use array_reduce to summarize the array into an associative array using the code as the key. Use array_values to convert the associative array into a simple array.
$myArray = ....
$result = array_values(array_reduce($myArray, function($c, $v){
if ( !isset( $c[ $v['code'] ] ) ) $c[ $v['code'] ] = array( 'code' => $v['code'], 'room' => array() );
$c[ $v['code'] ]['room'][] = $v['room'];
return $c;
},array()));
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[0] => Array
(
[code] => 1
[room] => Array
(
[0] => Array
(
[name] => Room-A
)
[1] => Array
(
[name] => Room-B
)
)
)
[1] => Array
(
[code] => 2
[room] => Array
(
[0] => Array
(
[name] => Vip-1
)
[1] => Array
(
[name] => Vip-2
)
)
)
)
This is the foreach() equivalent of Eddie's answer (I find it easier to read/maintain).
Code: (Demo)
$myArray = [
['code' => '1', 'room' => ['name' => 'Room-A']],
['code' => '1', 'room' => ['name' => 'Room-B']],
['code' => '2', 'room' => ['name' => 'Vip-1']],
['code' => '2', 'room' => ['name' => 'Vip-2']]
];
foreach ($myArray as $row) {
if (!isset($result[$row['code']])) {
$result[$row['code']] = ['code' => $row['code'], 'room' => [$row['room']]];
// ^------------^-- pushed deeper
} else {
$result[$row['code']]['room'][] = $row['room'];
// ^^-- pushed deeper
}
}
var_export(array_values($result));
This question is very similar to many pre-existing questions that want to group by a particular column. I was not able to find an exact duplicate to close with because the requirement of this question is to created a deeper structure to contain the room sub arrays.
Typically I would write:
if (!isset($result[$row['code']])) {
$result[$row['code']] = $row;
to cut down on syntax, but the new output structure must be applied to both the if and the else.
To avoid key duplication/collision, the room subarrays need to be pushed/indexed to a lower level.
In the end, the technique has been demonstrated here many, many times on StackOverflow. You target an element value to group by and use that value as the temporary key as you iterate the input array. Checking if the temporary keys exist or not is the fastest way to determine if a group is new or previously encountered. When you are done, call array_values() to remove the temporary keys (re-index the array).

How to populate missing array data by flipping 2nd and 3rd level keys?

I have a multidimensional array and I need to ensure that paired/related subarrays are generated in the deepest level of my array.
The idea is that subarrays [65][1] and [155][1] should exist. At the same time, subarrays [65][2] and [155][2] should exist.
In other words, [nn][1] and [nn][2] must exist.
I would like to be able to automatically add subarrays which do not exist. I do not know how to do it with PHP.
So, I am looking for a code which goes through the array and creates subarrays which do not exist.
Here is an example.
Array (
[65] => Array (
[1] => Array (
[2] => Array (
[points] => 0000000600
[competition] => 0000000011
)
)
)
[155] => Array (
[1] => Array (
[2] => Array (
[points] => 0000000900
[competition] => 0000000011
)
)
[2] => Array (
[1] => Array (
[points] => 0000000750
[competition] => 0000000025
)
)
)
}
However, the subarray [65][2] does not exist.
As said, I am looking for a code which goes through the array and creates subarrays which do not exist.
The result should look like this:
Array (
[65] => Array (
[1] => Array (
[2] => Array (
[points] => 0000000600
[competition] => 0000000011
)
)
/* this should be added automatically */
[2] => Array (
[1] => Array (
[points] => 0000000000
[competition] => 0000000000
)
)
)
/* */
[155] => Array (
[1] => Array (
[2] => Array (
[points] => 0000000900
[competition] => 0000000011
)
)
[2] => Array (
[1] => Array (
[points] => 0000000750
[competition] => 0000000025
)
)
)
}
Notice that the default data is assign to a new subarray which is assigned 2nd and 3rd level keys using the 3rd and 2nd level keys respectively.
If I understood you correctly, all the elements in your main array are themselves arrays, and each of them must have both a [1] and a [2] element. You can check for this with the array_key_exists() function. Something like:
foreach($rg as $rgkey) {
if(!array_key_exists(1,$rg[$rgkey])) {
/* code to initialize $rg[$rgkey][1] */ }
if(!array_key_exists(2,$rg[$rgkey])) {
/* code to initialize $rg[$rgkey][2] */ }
}
Traverse the top two levels of your structure and then check for the expected third level key, if it doesn't exist, populate the new subarray with the default data using flipped keys.
Code: (Demo)
foreach ($rg as $id1 => $level2) {
foreach ($level2 as $id2 => $level3) {
$id3 = key($level3);
if (!isset($level2[$id3])) {
$rg[$id1][$id3][$id2] = [
'points' => '0000000000',
'competition' => '0000000000'
];
}
}
}
var_export($rg);
Output:
array (
65 =>
array (
1 =>
array (
2 =>
array (
'points' => '0000000600',
'competition' => '0000000011',
),
),
2 =>
array (
1 =>
array (
'points' => '0000000000',
'competition' => '0000000000',
),
),
),
155 =>
array (
1 =>
array (
2 =>
array (
'points' => '0000000900',
'competition' => '0000000011',
),
),
2 =>
array (
1 =>
array (
'points' => '0000000750',
'competition' => '0000000025',
),
),
),
)

Counting multiple values from a query

I'm getting an array of this type from the database: (I can't change the type of data received, as it comes from an outside source)
Array
(
[0] => Es\Result Object
(
[_hit:protected] => Array
(
[_index] => website
[_type] => structure
[_id] => 8
[_score] => 0.625
[_source] => Array
(
[name] => Test1
[locality] => Array
(
[locality] => Bologna
[sign] => BO
[province] => Array
(
[province] => Bologna
[region] => Array
(
[region] => Emilia Romagna
)
)
)
)
)
)
[1] => Elastica\Result Object
(
[_hit:protected] => Array
(
[_index] => website
[_type] => structure
[_id] => 6
[_score] => 0.625
[_source] => Array
(
[name] => Test2
[locality] => Array
(
[locality] => Bologna
[sign] => BO
[province] => Array
(
[province] => Bologna
[region] => Array
(
[region] => Emilia Romagna
)
)
)
)
)
)
......
I enter into a json object value of "locality" and count how many "locality" are equal, for example:
foreach ($results as $result) {
$source = $result->getSource();
$locality = $source['locality']['locality'];
$dataLocality[] = array(
'type' => 'locality',
'label' => $locality,
'count' => 1, //How to increase the count here?
);
}
I tried to put everything in a loop but I can't count the values ​​correctly.
Is there a way to do this?
EDIT
This should be the result that I get:
let's say I get the array has 3 "locality":
2 "foo"
1 "bar"
$dataLocality =
Array
(
[0] => Array
(
[type] => 'locality'
[locality] => 'foo'
[count] => 2
)
[1] => Array
(
[type] => 'locality'
[locality] => 'bar'
[count] => 1
)
)
Does the value of $locality exist in the array? If no, then store it with a count of 1. If yes, then add 1 to the count.
foreach ($results as $result) {
$source = $result->getSource();
$locality = $source['locality']['locality'];
// Manually specify the array key. This makes life much easier down the road,
// especially when you need to find items in the array.
if ( !isset($dataLocality[$locality]) ) {
$dataLocality[$locality] = array('type' => 'locality',
'label' => $locality,
'count' => 1);
} else {
$dataLocality[$locality]['count'] += 1;
}
}
Declare an array (say $dataLocality) outside your foreach loop. In each loop you search for an existant locality in $datalocality (if $result is in $dataLocality). If there is one, you increment the counter by $dataLocality[$indexOfFounding]['count']++.
This off course requires the adding of your array of 'type', 'label' and 'count' if you don't find any locality in $dataLocality.
After the foreach loop you can go through your array and output or do anything with your results.
If you are needing the count of locality array then make use of count Try:
foreach ($results as $result) {
$source = $result->getSource();
$locality = $source['locality']['locality'];
$dataLocality[] = array(
'type' => 'locality',
'label' => $locality,
'count' => count($source['locality']), //get locality array count
);
}
Thanks to #Dave's reply I solved the problem, but since I could not have named keys, I added outside the loop:
$dataLocality = array_values($dataLocality);
so the complete code to solve the problem, but on occasions someone had a problem similar to mine is:
foreach ($results as $result) {
$source = $result->getSource();
if(!isset($dataLocality[$locality = $source['locality']['locality']])) {
$dataLocality[$locality] = array(
'type' => 'locality',
'label' => $locality,
'count' => 1,
);
} else {
$dataLocality[$locality]['count']++;
}
}
$dataLocality = array_values($dataLocality);

Array unique multidimensional on one column

I have a big array like this this one (only 5 entries here)
Array
(
[1] => Array
(
[last_token] => atokenforexample
[idmembre] => 31800
[key] => 821fbe3f4623649562f75a3de132c908
[idmembre_mobile] => 230106
)
[2] => Array
(
[last_token] => atoken1
[idmembre] => 83586
[key] => 0854ea148c95c08a30c623a313e645a9
[idmembre_mobile] => 126634
)
[3] => Array
(
[last_token] => atoken1
[idmembre] => 138727
[key] => 622c0803a8f662c1df852001017b5db8
[idmembre_mobile] => 119326
)
[4] => Array
(
[last_token] => atokensocool
[idmembre] => 163737
[key] => 8bab884bf46c14abfceaef7abcdf14f9
[idmembre_mobile] => 222066
)
[5] => Array
(
[last_token] => WOWanothetoken
[idmembre] => 236345
[key] => 41c17896091d9417b305e70541039249
I need to get a unique array from this on only one column, the last_token :
So here i need to swipe the array with key 3 (array[3]) because his last_token is the same as array[2][last_token].
Array unique can't work here.. :(
To save the last occurrence:
foreach($array as $value) {
$result[$value['last_token']] = $value;
}
$result = array_values($result);
Or to save the first occurrence:
foreach(array_reverse($array) as $value) {
$result[$value['last_token']] = $value;
}
$result = array_reverse(array_values($result));
Probably a more elegant way but I'm starving and off to eat.

Sort a set of arrays based on a single key:value pair in php

Found a question which already explains this - How to sort an array of associative arrays by value of a given key in PHP?
I have an array (A1) of arrays (A2). I would like to sort all A2s inside A1 based on a key:value pair in A2
The structure is like this
A1
->A2-1
->K1:Some Value
->K2:ValB
->A2-2
->K1:Other Value
->K2:ValB1
->A2-3
->K1:Some Value
->K2:ValB2
->A2-4
->K1:Other Value
->K2:ValB3
I would like to sort the arrays in A1 so that all A2s for which K1's value is Other Value are bunched together and all A2s for which K1's value is Some Value are bunched together
So after the sorting, the final order of arrays in A1 should be A2-2, A2-4, A2-1, A2-3. Is there a function in PHP using which I can do this? Or do I have to parse through the entire array and do the sorting?
Thanks.
http://php.net/manual/en/function.array-multisort.php
If that doesn't fit, there's a lot of other array functions http://www.php.net/manual/en/ref.array.php
Have a try with:
$A1 = array(
'A2-1' => array(
'K1' => 'Some Value',
'K2' => 'ValB',
),
'A2-2' => array(
'K1' => 'Other Value',
'K2' => 'ValB1',
),
'A2-3' => array(
'K1' => 'Some Value',
'K2' => 'ValB2',
),
'A2-4' => array(
'K1' => 'Other Value',
'K2' => 'ValB3',
)
);
function mySort($a, $b) {
if ($a['K1'] == $b['K1']) {
return strcmp($a['K2'], $b['K2']);
} else {
return strcmp($a['K1'], $b['K1']);
}
}
uasort($A1, 'mySort');
print_r($A1);
output:
Array
(
[A2-2] => Array
(
[K1] => Other Value
[K2] => ValB1
)
[A2-4] => Array
(
[K1] => Other Value
[K2] => ValB3
)
[A2-1] => Array
(
[K1] => Some Value
[K2] => ValB
)
[A2-3] => Array
(
[K1] => Some Value
[K2] => ValB2
)
)
You need something like:
usort($array, function($a, $b)
{
return strcmp($a['k1'], $b['k1']);
});
You may need to replace strcmp with a different sorting function (or operators) because it's unclear exactly what you are doing.
strategy:
1. find unique values, put them aside.
2. loop through unique values
2.1 loop origial array
2.2 store sub array in $out if unique val = original val
<?php
$i=0;
$a3d = array(
$i++ => array(0=>'Some Value',1=>'ValB'),
$i++ => array(0=>'Other Value',1=>'ValB1'),
$i++ => array(0=>'Some Value',1=>'ValB2'),
$i++ => array(0=>'Zome moar',1=>'ValB4'),
$i++ => array(0=>'Other Value',1=>'ValB3'),
$i++ => array(0=>'Zome Moar',1=>'ValB4'),
);
print_r($a3d);
foreach ($a3d as $a2d){
$uniq[]= $a2d[0];
}
$uniq = array_unique($uniq);
sort($uniq);
print_r($uniq);
foreach ($uniq as $v){
foreach ($a3d as $kk => $a2d){
if ($a2d[0] == $v){
$out[]= $a2d;
unset($a3d[$kk]); // <--avoid rechecking elements
}
}
}
print_r(count($a3d));
print_r($out);
?>
$ php sort_array.php
Array
(
[0] => Array
(
[0] => Some Value
[1] => ValB
)
[1] => Array
(
[0] => Other Value
[1] => ValB1
)
[2] => Array
(
[0] => Some Value
[1] => ValB2
)
[3] => Array
(
[0] => Zome moar
[1] => ValB4
)
[4] => Array
(
[0] => Other Value
[1] => ValB3
)
[5] => Array
(
[0] => Zome Moar
[1] => ValB4
)
)
Array
(
[0] => Other Value
[1] => Some Value
[2] => Zome Moar
[3] => Zome moar
)
0Array
(
[0] => Array
(
[0] => Other Value
[1] => ValB1
)
[1] => Array
(
[0] => Other Value
[1] => ValB3
)
[2] => Array
(
[0] => Some Value
[1] => ValB
)
[3] => Array
(
[0] => Some Value
[1] => ValB2
)
[4] => Array
(
[0] => Zome Moar
[1] => ValB4
)
[5] => Array
(
[0] => Zome moar
[1] => ValB4
)
)

Categories