Make a new array form multidimensional array based on search conditions - php

I have a multidimensional array. I want to search values(username IE jon) and count total "YES" for a specific username.
IE As per below array Andew is repeated three times Index 1,3,4 and its value is "YES" So Andrew's total "YES" count value = 3
Jon is repeated two times but its value is "NO" so it's value = 0
Array
(
[0] => Array
(
[0] => Jon
[1] => NO
)
[1] => Array
(
[0] => Andew
[1] => NO
)
[2] => Array
(
[0] => Walid
[1] => YES
)
[3] => Array
(
[0] => Andew
[1] => YES
)
[4] => Array
(
[0] => Andew
[1] => YES
)
[5] => Array
(
[0] => Jon
[1] => NO
)
[6] => Array
(
[0] => Andew
[1] => YES
)
)
I want to make the user as key and value = count the total number of "Yes".
OUTPUT
Array
(
john => 0,
Andew => 3
Walid => 1
)
Anyone, please suggest a possible solution?
Thanks

You may use array_reduce:
$stats = array_reduce($array, static function ($stats, $entry) {
$stats[$entry[0]] = ($stats[$entry[0]] ?? 0) + ($entry[1] === 'YES' ? 1 : 0);
return $stats;
});
This builds up a $stats array, sets its initial value to 0 for each person and increments it by 1 whenever a YES is found.
Demo: https://3v4l.org/NmZ7G

If you just need the count of 'YES', then the below will output a count.
$count_array = [];
foreach($array as $values){
if(!isset($count_array[$values[0]])){
$count_array[$values[0]] = 0;
}
if($values[1] === 'YES'){
$count_array[$values[0]] ++;
}
}
print_r($count_array);

(Not that different from #Jeto's array_reduce.)
A simple foreach:
<?php
$data =
[
['Brian', 'YES'],
['Brian', 'YES'],
['Charles', 'NO'],
['Charles', 'YES'],
['Nicola', 'NO']
];
foreach($data as list($name, $yes_no))
$yes_counts[$name] = ($yes_counts[$name] ?? 0) + (int) ($yes_no === 'YES');
var_export($yes_counts);
Output:
array (
'Brian' => 2,
'Charles' => 1,
'Nicola' => 0,
)

Related

Remove empty string in array of strings

It seems that there are dozens of topic with similar problem, and mostly all have the same answer: use array_filter, array_map. The problem is that I used them, but it didn't quite help. So I have an array (is built from data in csv file):
Array
(
[0] => Array
(
[0] => name
[1] => title
[2] => email
)
[1] => Array
(
[0] => First
[1] => title 1
[2] => email1#ex.com
)
[2] => Array
(
[0] => second
[1] => title 1
[2] => email2#ex.com
)
[3] => Array
(
[0] =>
)
[4] => Array
(
[0] => third
[1] => title 1
[2] => email3#ex.com
)
[5] => Array
(
[0] =>
)
[6] => Array
(
[0] =>
[1] =>
[2] =>
)
)
I have to delete all empty arrays. So I use such code:
while (($row = fgetcsv($file, 8192, ';')) !== false) {
if (array(null) !== $row) { // ignore blank lines
$csv[] = $row;
}
}
$array = array_filter(array_map('array_filter', $csv));
$array now is:
Array
(
[0] => Array
(
[0] => name
[1] => title
[2] => email
)
[1] => Array
(
[0] => First
[1] => title 1
[2] => email1#ex.com
)
[2] => Array
(
[0] => second
[1] => title 1
[2] => email2#ex.com
)
[3] => Array
(
[0] => third
[1] => title 1
[2] => email3#ex.com
)
[4] => Array
(
[1] =>
)
)
Why there is a 4th array with empty value? I need to get rid of it.
gettype($array[4][1]) = string
UPDATE
The csv has empty rows, and even just a ";" delimiter without any string. I cannot influence on the process of inserting data into this csv.
The csv looks like this:
1 row: name;title;email
2 row: First;title 1;email1#ex.com
3 row: second;title 1;email2#ex.com
4 row:
5 row: third;title 1;email3#ex.com
6 row:
7 row: ; ;
and mostly all have the same answer: use array_filter, array_map.
array_filter is a good approach, but I wouldn't use array_map, but array_reduce:
$array = array_filter(
$csv,
function ($value) {
return 0 < array_reduce(
$value,
function ($carry, $item) {
return empty(trim($item)) ? $carry : $carry + 1;
},
0
);
}
);
With array_reduce, I count the non-empty elements in an array. And if there are zero non-empty elements, the array is thrown away with array_filter.
For reference, the PHP 7.4-syntax, which looks nicer in my eyes, but could be a bit confusing at first
$array = array_filter(
$csv,
fn ($val) => 0 < array_reduce(
$val,
fn ($carry, $item) => empty(trim($item)) ? $carry : $carry + 1,
0
)
);

How to create dynamic array using existing array

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

Sort array by key value and then get 5 highest and lowest values in array

I have an array called "playersArray" that looks like this:
Array (
[0] => Array ( [name] => Joe [holders] => 0 )
[1] => Array ( [name] => Bob [holders] => 100 )
[2] => Array ( [name] => Jake [holders] => 100 )
[3] => Array ( [name] => Mike [holders] => 100 )
[4] => Array ( [name] => Tim [holders] => -0.0145 )
[5] => Array ( [name] => Frank[holders] => 100 )
[6] => Array ( [name] => Scott [holders] => 0.0583 )
[7] => Array ( [name] => Doug[holders] => 0.1308 )
[8] => Array ( [name] => Tommy [holders] => 0.2516 )
[9] => Array ( [name] => Eric [holders] => 100 )
)
I have a function to sort this array by the "holders" value:
function compareHolders($a, $b) {
$aPoints < $a['holders'];
$bPoints < $b['holders'];
return strcmp($aPoints, $bPoints);
}
I loop through another array to create this array:
foreach ($players as $player) {
$player['name'] = $athlete['name'];
$player['holders'] = $total_result_yesterday;
$playersArray[] = $player;
}
I am trying to sort the array by "holder" value:
usort($playersArray, 'compareHolders');
print_r($playersArray);
Finally, I am trying to get the 5 highest and 5 lowest "holder" values in the newly sorted array:
$first_5_players = array_slice($playersArray, 0, 5, true);
$last_5_players = array_slice($playersArray, -5);
However, the sorting is not working correctly. The values due not show in sequential order as desired. How can I get the sorting to work correctly? Thank you!
your sorting function compareHolders is not correct. $aPoints and $bPoints are not defined. Since values for holders key are numeric you can use the comparision operators. Try doing following:
function compareHolders($a, $b) {
if ($a['holders'] == $b['holders']) {
// return 0 if equal
return 0;
}
return ($a['holders'] > $b['holders']) ? -1 : 1;
}
You are not actually comparing the two values in compareHolders(), because you're not declaring $aPpoints and $bPoints.
This should work:
function compareHolders($a, $b) {
$aPoints = $a['holders'];
$bPoints = $b['holders'];
return strcmp($aPoints, $bPoints);
}
or alternatively you could just return:
return strcmp($a['holders'], $b['holders']);
And then you could get rid of the strcmp(), since you're not comparing strings.

how to count the array values with key

I have array like this i need to count by array values
Array ( [Cop] => Array ( [0] => Dozen [1] => Dozen [2] => Akls [3] => Akls ) [MSN] => Array ( [0] => Dozen ) [NeK] => Array ( [0] => Suhan [1] => Ebao ) [NetSE] => Array ( [0] => SuZhan [1] => Guhang ) )
For example
Array ( [Cop] => Array ( [0] => Dozen [1] => Dozen [2] => Akls [3] => Akls ))
In the Cop key i have two different values for cop so i need cop should be 2
Cop - 2
MSn - 1
NeK - 2
NetSE - 2
I need the count like above how can i do this ?
Try simply using array_map,count,& array_unique like as
array_map(function($v) {
return count(array_unique($v));
}, $arr);
Use array_unique() and then count.
count(array_unique($array['Cop']));// output 2
If you want to print for every key do following:
$array = array('Cop'=>array('Dozen','Dozen','Akls','Akls'), 'MSN'=> array('Dozen'), 'NeK'=> array('Suhan','Ebao'));
foreach($array as $key => &$value) {
$value = count(array_unique($array[$key]));
}
print_r($array);
Output:
Cop = 2
MSN = 1
NeK = 2
You should use array_count_values() for that, here's an example:
$data = array('cop' => array(0 => 'test', 1 => 'test', 2 => 'test2'));
foreach($data as $item){
$result = array_count_values($item);
print_r($result);
}
Outputs:
Array
(
[test] => 2
[test2] => 1
)

Remove duplicate elements off a multi-dimension array

I have an array contain this data
Array
(
[id] => Array
(
[0] => 1
[1] => 10
[2] => 4
)
[age] => Array
(
[0] => 1
[1] => 1
[2] => 2
)
)
Now I want to remove duplicates from the ['age'] and leave the first one in tact.
So this would return
Array
(
[id] => Array
(
[0] => 1
[2] => 4
)
[age] => Array
(
[0] => 1
[2] => 2
)
)
Any ideas? Or is there a function already in place to do this?
Like Gordon said, you'd need a custom function to make the relationship but you can use http://php.net/manual/en/function.array-unique.php ?
Wouldn't it be better to have the keys of the age array the corresponding values of the id array?
<?php
$array = array(
'id' => array(0 => 1, 1 => 10, 3 => 4),
'age' => array(0 => 1, 1 => 1, 2 => 2)
);
array_walk($array, 'dupe_killer');
print_r($array);
function dupe_killer(&$value, $key)
{
$value = array_unique($value);
}
?>
You could try this
$array = array('id' => array(1,10,4), 'age'=>array(1,1,2));
$age_array = array();
foreach ($array['age'] as $key => $val) {
if (in_array($val, $age_array))
unset($array['id'][$key], $array['age'][$key]);
$age_array[] = $val;
}
print_r($array);
this returns Array ( [id] => Array ( [0] => 1 [2] => 4 ) [age] => Array ( [0] => 1 [2] => 2 ) )
Regards
Luke

Categories