I need help working with arrays. I have an array of data from a MySQL query. After printing it in a for loop, I get the following array_flip:
Array (
[Duru 60] => 0
[Maxwell 50] => 1
[Fashanu 70] => 2
[Nwankwo 80] => 3
[Obi 0] => 4
)
The array value is a combination of 2 fields name and total score. What I want to achieve is an array like so:
Array (
[Duru 60] => 60
[Maxwell 50] => 50
[Fashanu 70] => 70
[Nwankwo 80] => 80
[Obi 0] => 0
)
What I want to achieve is to change the default array numeric keys (0,1,2,3,4) to total score obtained from the query.
Here is the code that gave the first array block:
PHP code begins
$dataA = array();
foreach($data as $key => $val){
$dataC = $val['lastname']." ".$val['total'];
array_push($dataA,($dataC));
}
$dataD = (array_flip($dataA));
print_r($dataD);
$dataA = array();
foreach($data as $key => $val){
$dataK = $val['lastname']." ".$val['total'];
$dataV = $val['total'];
$dataA[$dataK] = $dataV;
}
print_r($dataA);
Try this:
$dataA = array();
foreach($data as $key => $val){
$dataC = $val['lastname']." ".$val['total'];
$dataA[$dataC] = $val['total'];
}
print_r($dataA);
Why can't you just do:
$newData = array();
foreach($data as $key => $val) {
$newData[$val['lastname'] . ' ' . $val['total']] = $val['total'];
}
print_r($newData);
Related
I have a multidimensional array which has keys and key has values or have another array with keys and values so I want to search by keys but in input like 230 is user input
and it will go to 3 then 4 then 1 if result is a value but not an array it must print the value like
input = 230 result should be = "3-4-1"
so I need to str_split the number and search it 1 by 1 if first number is array then look for second kinda
edit1 = I found the way to split the key
//edit1
$keys = "021";
$keysSplit =str_split($keys, strlen($keys)/strlen($keys));
echo $keys[0];
//edit 1 ends
$arr = [0 => [0=>"1-1", 1 => "1-2" , 2=>"1-3", 3=>[0=>"1-4-1", 1 => "1-4-2" , 2=>"1-4-3"]],
1 => [0=>"2-1", 1 => "2-2" , 2=>"2-3"],
2 => [0=>"3-1", 1 => "3-2" , 2=>"3-3", 3=>[0 =>"3-4-1" , 1=> "3-4-2"]],
];
$keys = "021";
function searchByKey($array , $keys){
$result = [];
$keys = "021";
$keys =str_split($keys, strlen($keys)/strlen($keys));
$key1 = $keys[0];
$key2 = $keys [1];
$key3 = $keys [2];
foreach ($array as $key1 => $value){
if (is_array($value)){
$key1 = null;
$key1 = $key2;
$key2 = $key3;
return searchByKey($value , $key1);
}
else {
$result=$value;
echo $result;
}
}
}
$arr = searchByKey($arr, $keys);
The function only works as key and value given and it will print every key and value on the key it asked first so its not the thing I wanted to do could anyone help and explain?
Answer given by #Anggara I made it in to function ;
$input = "11";
function searchByNumber($array, $input){
$result = $array;
for ($i = 0; $i < strlen($input); $i++) {
if (is_array($result)) {
$result = $result[$input[$i]];
} else {
$result = "Does not exists";
break;
}
}
echo $result;
}
$arr = searchByNumber($arr, $input);
You can access char in string like accessing an array. For example:
$input = "230";
// $input[0] is "2"
// $input[1] is "3"
// $input[2] is "0"
So my approach is to loop for each character in input key, and look for corresponding value in $arr. Each iteration will set found array element into variable $result. If the searched key does not exist (ex: "021"), print error message.
<?php
$arr = [
0 => [
0 => "1-1",
1 => "1-2",
2 => "1-3",
3 => [
0 => "1-4-1",
1 => "1-4-2",
2 => "1-4-3"
]
],
1 => [
0 => "2-1",
1 => "2-2",
2 => "2-3"
],
2 => [
0 => "3-1",
1 => "3-2",
2 => "3-3",
3 => [
0 => "3-4-1",
1 => "3-4-2"
]
],
];
$input = "230";
$result = $arr;
for ($i = 0; $i < strlen($input); $i++) {
if (is_array($result)) {
$result = $result[$input[$i]];
} else {
$result = 'Can not traverse path';
break;
}
}
echo $result;
After splitting the keys
for($i=0;$i<strlen($keys);$i++){
$arr = $arr[$keys[$i]];
}
if(is_array($arr)){
echo json_encode($arr);
}else{
echo $arr;
}
You need a loop, which will go through the keys one by one and assigning into the array.
I just started learning php and I have this issue. I'm trying to loop through this array to get the total value of each key and output the student with the highest number. I'd really appreciate your inputs
$students = array(
'Mary' => [20,45,12],
'Grace' => [40,78,56],
'John' => [61,37,58]
);
The expected output should be Grace but i can't seem to get it to work.
You don't have to loop. Just calculate all the totals
$totals = array_map('array_sum', $students);
then output the key of the array with the maximum total.
echo array_keys($totals, max($totals))[0];
Something like this maybe assuming all grades will be positive
$students = array(
'Mary' => [20,45,12],
'Grace' => [40,78,56],
'John' => [61,37,58]
);
$highest_grade = 0;
$higest_person = "";
foreach($students as $key => $value) {
$max = max($value);
if ($highest_grade <= $max) {
$highest_grade = $max;
$highest_person = $key;
}
}
echo $highest_person . '->' . $highest_grade;
Output is using http://phptester.net/
Grace->78
I am using Spout Excel reader to read Excel files from php code and saving into a multidimensional array in PHP variable,Array looks like this
$array = [
[
'id[0]' => 'BX-78',
'Name[0]' => 'XXX',
'Address[0]' => 'YUUSATD'
],
[
'id[1]' => 'BX-79',
'Name[1]' => 'YYY',
'Address[1]' => 'DHJSHDJGY'
],
[
'id[2]' => 'BX-80',
'Name[2]' => 'ZZZ',
'Address[2]' => 'DDSDSDA'
]
[
'id[3]' => 'BX-78',
'Name[3]' => 'AAA',
'Address[3]' => 'FSDSDS'
][
'id[4]' => 'BX-81',
'Name[4]' => 'XXX',
'Address[4]' => 'DSDSDSD'
]];
Now i want to show duplicate data from above array using two keys ['id'] and ['name'] if id repeats show as duplicate data,
If name repeats show that row as duplicate data if both are duplicate show as again duplicate row
Otherwise it is unique row.
I have tried using multidimensional array sorting but it is using only one key to match data in rows.
foreach ($arrExcelData as $v) {
if (isset($arrExcelData[$v[0]])) {
// found duplicate
continue;
}
// remember unique item
$arrExcelData3[$v[0]] = $v;
}
// if you need a zero-based array, otheriwse work with $_data
$arrExcelData2 = array_values($arrExcelData3);
Edited : Expected Output Result :
Matching Rows:
Id Name Address
-------------------------
BX-78 XXX YUUSATD
BX-78 AAA DDSDSDA
BX-81 XXX DSDSDSD`
If you want to list the duplicate values, I think the address of the second match should be FSDSDS as there is not item with name AAA and value DDSDSDA:
BX-78 AAA FSDSDS
If that is the case, what you could do is to first use a double foreach to mark the arrays that contain a duplicate id or name by for example adding a property named id and name except when the array is itself in the second loop.
After this loop, you can tell which arrays are the duplicate ones. Instead of using a corresponding index 0 as in id[0], I have used reset and next so it is not tied to these indexes.
To get the filtered result you could use array_reduce to check for the array keys and unset them.
For example:
foreach ($array as $index => $a) {
foreach ($array as $v) {
if ($v === $a) continue;
if (reset($v) === reset($a)) $array[$index]["id"] = "duplicate";
if (next($v) === next($a)) $array[$index]["name"] = "duplicate";
}
}
$array = array_reduce($array, function($carry, $item) {
if (array_key_exists("id", $item) || array_key_exists("name", $item)) {
unset($item["id"], $item["name"]);
$carry[] = $item;
}
return $carry;
}, []);
print_r($array);
Result
Array
(
[0] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
[1] => Array
(
[id[3]] => BX-78
[Name[3]] => AAA
[Address[3]] => FSDSDS
)
[2] => Array
(
[id[4]] => BX-81
[Name[4]] => XXX
[Address[4]] => DSDSDSD
)
)
See a php demo
I've this very pragmatic approach:
$spout_output = [
[
'id[0]' => 'BX-78',
'Name[0]' => 'XXX',
'Address[0]' => 'YUUSATD'
],
[
'id[1]' => 'BX-79',
'Name[1]' => 'YYY',
'Address[1]' => 'DHJSHDJGY'
],
[
'id[2]' => 'BX-80',
'Name[2]' => 'ZZZ',
'Address[2]' => 'DDSDSDA'
],
[
'id[3]' => 'BX-78',
'Name[3]' => 'AAA',
'Address[3]' => 'FSDSDS'
],
[
'id[4]' => 'BX-81',
'Name[4]' => 'XXX',
'Address[4]' => 'DSDSDSD'
]];
// store id to row, and name to row mappings.
// id and name will be keys, value will be an array of indexes of the array $spout_output
$id_to_rows = array();
$name_to_rows = array();
$duplicate_ids = array();
$duplicate_names = array();
foreach($spout_output as $row => $data)
{
$key_id = 'id['.$row.']';
$key_name = 'Name['.$row.']';
if(!isset($data[$key_id]))
continue;
$value_id = $data[$key_id];
$value_name = $data[$key_name];
if(!isset($id_to_rows[$value_id]))
{
$id_to_rows[$value_id] = array();
}
else
{
if(!isset($duplicate_ids[$value_id]))
{
$duplicate_ids[$value_id] = $id_to_rows[$value_id];
}
$duplicate_ids[$value_id][] = $row;
}
if(!isset($name_to_rows[$value_name]))
{
$name_to_rows[$value_name] = array();
}
else
{
if(!isset($duplicate_names[$value_name]))
{
$duplicate_names[$value_name] = $name_to_rows[$value_name];
}
$duplicate_names[$value_name][] = $row;
}
$id_to_rows[$value_id][] = $row;
$name_to_rows[$value_name][] = $row;
}
echo 'Duplicates:';
echo '<br>';
$shown_rows = array();
foreach($duplicate_ids as $id => $rows)
{
foreach($rows as $nr)
{
echo $id . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
echo '<br>';
$shown_rows[] = $nr;
}
}
foreach($duplicate_names as $name => $rows)
{
foreach($rows as $nr)
{
// if already shown above, skip this row
if(in_array($nr, $shown_rows))
continue;
echo $spout_output[$nr]['id['.$nr.']'] . '|' . $spout_output[$nr]['Name['.$nr.']'] . '|' . $spout_output[$nr]['Address['.$nr.']'];
echo '<br>';
$shown_rows[] = $nr;
}
}
Outputs:
Duplicates:
BX-78|XXX|YUUSATD
BX-78|AAA|FSDSDS
BX-81|XXX|DSDSDSD
I think your 'wanted output' contains an error in the address?
Anyway, with my code above I think you'll have enough mapped data to produce the output you want.
You could do something like this:
$dupes = [];
$current = [];
foreach ($array as $index => $entry) {
$idKey = "id[$index]";
$nameKey = "Name[$index]";
if (array_key_exists($entry[$idKey], $current)) {
$dupes[] = [$entry, $current[$entry[$idKey]]];
}
elseif (array_key_exists($entry[$nameKey], $current)) {
$dupes[] = [$entry, $current[$entry[$nameKey]]];
}
else {
$current[$entry[$idKey]] = $current[$entry[$nameKey]] = $entry;
}
}
print_r($dupes);
Which results in an array containing each set of duplicates (array of arrays):
Array
(
[0] => Array
(
[0] => Array
(
[id[3]] => BX-78
[Name[3]] => AAA
[Address[3]] => FSDSDS
)
[1] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
)
[1] => Array
(
[0] => Array
(
[id[4]] => BX-81
[Name[4]] => XXX
[Address[4]] => DSDSDSD
)
[1] => Array
(
[id[0]] => BX-78
[Name[0]] => XXX
[Address[0]] => YUUSATD
)
)
)
Demo here: https://3v4l.org/JAtNU
In case someone of you are searching unique values by key.
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
This function just takes multidimensional array and key value of field you need.
Then takes value of given array one by one (smaller arrays).
Then traverses given array and looking if taken key-value pair matches with given key.
After that if taken key-value pair matches with given key function just inserts smaller array in temporary array (array with unique values).
Don't forget to increment indexes of arrays ($i).
Then return array you got (with unique values) after function ends work.
$cuisines = RestaurantProfile::select('cuisines')->get();
$cuisines_array = array();
foreach ($cuisines as $cuisine) {
$string = implode(",",json_decode($cuisine, true));
$array = explode(",", $string);
foreach ($array as $single) {
if (!in_array($single, $cuisines_array)) {
$cuisines_array[] = $single;
}
}
}
dd($cuisines_array);
I want $cuisines_array to have something like
array:33 [▼
0 => "Afghani"
1 => "Mughlai"
2 => "Chinese"
3 => "Indian"
4 => "continental"
5 => "south indian"
6 => "mughlai"
But I am getting as in the screenshot: output screenshot
My Cuisines attribute in table is database table.
Any leads?
You can use array_slice() :
...
foreach (array_slice($array, 0, 6) as $single) {
...
array_slice()
returns the sequence of elements from the array array as specified by
the offset and length parameters
I have an array like below, and I want to do the total of values in a spefic manner where all values of val1_(.*) {regular expressions}, and similarly other values.
I have only specific vals like val1, val2, and val3.
My array is like:
$stats = Array
(
[ADDED_NEW_2012_06_12] => 16
[ADDED_OLD_2012_06_12] => 10
[ADD_LATER_2012_06_12] => 12
[ADDED_NEW_2012_06_11] => 16
[ADDED_OLD_2012_06_11] => 10
[ADD_LATER_2012_06_11] => 12
)
Can you please tell me how can i obtain my result. I don't know how to add such values using regex in php. Please help.
You don't necessarily need a regular expression if you can identify the values by the first part of the key.
Iterate over the array and create a new array with one element for each valX:
$totals = array();
// iterate over the array
foreach($array as $key => $value) {
$k = substr($key, 0, strpos($key, '_')); // get the first part (i.e. `valX`)
if(!isset($totals[$k])) { // if $totals['valX'] does not exist, initialize
$totals[$k] = 0;
}
$totals[$k] += $value; // sum
}
Reference: foreach, substr, strpos, isset
Do you mean this?
$array = array (
'val1_2012_06_12' => 16,
'val2_2012_06_12' => 10,
'val3_2012_06_12' => 12,
'val1_2012_06_11' => 16,
'val2_2012_06_11' => 10,
'val3_2012_06_11' => 12,
);
$sums = array();
foreach ($array as $key => $value) {
$regex = '~(?P<prefix>val\d+)_\d{4}_\d{2}_\d{2}~';
if (preg_match($regex, $key, $matches)) {
$sums[$matches['prefix']] += $value;
}
}
It will produce something like this, it will group sums by prefixes:
Array
(
[val1] => 32
[val2] => 20
[val3] => 24
)
Edit: updated to the refined question
You can match the key against a code, and create a sum from there like this with a simple foreach loop.
$array = array(
'ADDED_NEW_2012_06_12' => 16,
'ADDED_OLD_2012_06_12' => 10,
'ADD_LATER_2012_06_12' => 12,
'ADDED_NEW_2012_06_11' => 16,
'ADDED_OLD_2012_06_11' => 10,
'ADD_LATER_2012_06_11' => 12,
);
$sumarray = array();
foreach ($array as $key => $value)
{
$matches = array();
preg_match("/^(\w+?_\w+?)_/i", $key, $matches);
$key = $matches[1];
if (!isset($sumarray[$key]))
{
$sumarray[$key] = $value;
} else {
$sumarray[$key] = $sumarray[$key] + $value;
}
}
print_r($sumarray);
if you have just this tree type of value in array so you can use this:
$stats = Array(
'ADDED_NEW_2012_06_12' => 16,
'ADDED_OLD_2012_06_12' => 10,
'ADD_LATER_2012_06_12' => 12,
'ADDED_NEW_2012_06_11' => 16,
'ADDED_OLD_2012_06_11' => 10,
'ADD_LATER_2012_06_11' => 12
);
foreach($stats as $key => $value)
{
$substring=substr($key, 0 , 9);
if($substring=='ADDED_NEW')
#$ADDED_NEW += $value;
elseif($substring=='ADDED_OLD')
#$ADDED_OLD += $value;
else
#$ADD_LATER += $value;
}
echo 'ADDED_NEW : ' . $ADDED_NEW .'<br>ADDED_OLD : ' . $ADDED_OLD .'<br>ADD_LATER : ' . $ADD_LATER ;
Output :
ADDED_NEW : 32
ADDED_OLD : 20
ADD_LATER : 24
$sum = 0;
Foreach($object as $key=>$value){
$sum += $value;
}