How to append value in array with keys without getting overriding - php

i'm getting result in a foreach loop now i want to form a new array with keys and form that array with my new data. Now when i try to assign data it gets override to the previous one as it's not getting new index. how can i achive that so far i have done that:
foreach ($result as $key) {
$pickup_location = $key->locationid;
if (isset($pickup_location)) {
$pickup_location = $this->db->get_where('locations', array('id' => $pickup_location ))->row();
if (!empty($pickup_location)) {
$supplier_dashboard['pickup_location_name'] = $pickup_location->name_en;
}
}
$dropoff_location = $key->location_dropoff;
if (isset($dropoff_location)) {
$dropoff_location = $this->db->get_where('locations', array('id' => $dropoff_location ))->row();
if (!empty($dropoff_location)) {
$supplier_dashboard['dropoff_location_name'] = $dropoff_location->name_en;
}
}
$car_make = $key->car_id;
if (isset($car_make)) {
$car_details = $this->db->get_where('chauffeur_rates', array('chauffeur_id' => $car_make))->row();
if (!empty($car_details)) {
$supplier_dashboard['car_make'] = $car_details->chauffeur_make;
}
}
}
return $supplier_dashboard;
}
and my resulting array is:
Array
(
[pickup_location_name] => Seoul Downtown
[dropoff_location_name] => Disneyland Paris
[car_make] => makecar
)
however i have atleast 7 location names and car makes instead of getting added as a new array it overrides the previous one, i should have get the result as
Array
[0](
[pickup_location_name] => Seoul Downtown
[dropoff_location_name] => Disneyland Paris
[car_make] => makecar
)
Array
[1](
[pickup_location_name] => Seoul 1
[dropoff_location_name] => Disneyland 1
[car_make] => makecar
)
Array
[2](
[pickup_location_name] => Seoul 2
[dropoff_location_name] => Disneyland 2
[car_make] => makecar
)
... upto 7

Every time you looping the key of the array is always the same that's why you are getting overide the results. You need to put a key that is unique. You can try this
$i = 0; //First key
foreach ($result as $key){
$supplier_dashboard[$i]['pickup_location_name'] = $pickup_location->name_en;
$i++; //add +1 to the key so the next element not overrides
}

You have to add $key to array in which your record get added
use
$supplier_dashboard[$key]['pickup_location_name'] = //your code
instead of
$supplier_dashboard['pickup_location_name'] = //your code

Instead of adding the items the your array, you are directly setting the value in the top most collection.
Instad of
$myobject['foo'] = $value;
You need to do (where $iteration is the current position in your loop)
$myobject[$iteration]['foo'] = $value;
Try the following :
$carItemNumber = 0;
foreach ($result as $key) {
$pickup_location = $key->locationid;
if (isset($pickup_location)) {
$pickup_location = $this->db->get_where('locations', array('id' => $pickup_location ))->row();
if (!empty($pickup_location)) {
$supplier_dashboard[$carItemNumber]['pickup_location_name'] = $pickup_location->name_en;
}
}
$dropoff_location = $key->location_dropoff;
if (isset($dropoff_location)) {
$dropoff_location = $this->db->get_where('locations', array('id' => $dropoff_location ))->row();
if (!empty($dropoff_location)) {
$supplier_dashboard[$carItemNumber]['dropoff_location_name'] = $dropoff_location->name_en;
}
}
$car_make = $key->car_id;
if (isset($car_make)) {
$car_details = $this->db->get_where('chauffeur_rates', array('chauffeur_id' => $car_make))->row();
if (!empty($car_details)) {
$supplier_dashboard[$carItemNumber]['car_make'] = $car_details->chauffeur_make;
}
}
$carItemNumber++;
}
return $supplier_dashboard;

Related

How to show duplicate data in multidimensional array using PHP

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.

applying array_unique

I have code to get the address which is separated by space and then fetching area details about that address so each time sql result is stored in array "resultArray" and that result is pushed to another array "returnArray" which is then displayed in the format of json.I want to remove duplicate area_id in returnArray so I used "array_unique" but it's not working .Please give some suggestion.
Sample Code:
<?php
include_once 'main.php';
$dac = new Main();
$add = $_POST['address'];
$noLines = sizeof($add);
$resultArray=array();
$returnArray=array();
$returnArrayMain=array();
while ($noLines>0)
{
$resultArray=array();
$result = $dac->area_detail($add[$noLines-1]);
$count=mysql_num_rows($result);
while($row = mysql_fetch_assoc($result))
{
$resultArray[]=array('area_id' => $row['area_id'],'area_name' => $row['area_name'],'area_GISlat'=>$row['area_GISlat'],'area_GISlon'=>$row['area_GISlon']);
}
array_push($returnArray, $resultArray) ;
$noLines = $noLines-1;
}
$returnArrayMain = array_unique($returnArray);
echo json_encode($returnArrayMain);
?>
Here is solution with a testing associative array:
// this is testing array as you are using:
$resultArray = array(
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 11,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3'),
array(
'area_id' => 12,
'area_name' => 'test',
'area_GISlat'=>'test2',
'area_GISlon'=>'test3')
);
// take a temporary arry
$temporaryArr = array();
// initialize key's array
$arrayKey = array();
foreach ( $resultArray as $key => $values ) {
if ( !in_array($values, $temporaryArr) ) {
$temporaryArr[] = $values; // store values in temporary array
$arrayKey[$key] = true; // store all keys in another array
}
}
// now use array_intersect_key function for intersect both array.
$requiredArr = array_intersect_key($resultArray, $arrayKey);
echo "<pre>";
print_r($requiredArr);
Result:
Array
(
[0] => Array
(
[area_id] => 12
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
[1] => Array
(
[area_id] => 11
[area_name] => test
[area_GISlat] => test2
[area_GISlon] => test3
)
)
Removed duplicate arrays.
From PHP Manual:
array_intersect_key — Computes the intersection of arrays using keys for comparison
Side note:
Also add error reporting to the top of your file(s) right after your opening <?php tag
error_reporting(E_ALL);
ini_set('display_errors', 1);
try this
$returnArrayMain = array_map("unserialize", array_unique(array_map("serialize", $resultArray)));
try this..
$returnArrayMain = uniqueAssocArray($returnArray, 'area_id');
echo json_encode($returnArrayMain);
function uniqueAssocArray($array, $uniqueKey) {
if (!is_array($array)) {
return array();
}
$uniqueKeys = array();
foreach ($array as $key => $item) {
$groupBy=$item[$uniqueKey];
if (isset( $uniqueKeys[$groupBy]))
{
//compare $item with $uniqueKeys[$groupBy] and decide if you
//want to use the new item
$replace= ...
}
else
{
$replace=true;
}
if ($replace) $uniqueKeys[$groupBy] = $item;
}
return $uniqueKeys;
}

detect where elements in array moved

I have to be able to detect all changes in a "guild" (like an activity feed), with new and old data. The data is presented in this fashion, as an array:
{"GUILDMASTER":["foo"],"OFFICER":["bar","baz"],"MEMBER":["foobar","foobaz"]}
I need to detect if, for example, "bar" moves from his current rank down one (to "MEMBER"), it will output an array something like this:
[{"user":"bar","was_found_in":"OFFICER","now_found_in":"MEMBER"}]
What I currently have, below, only detects if a member has joined of left, is there any way to extend this to fulfill what I want it to?
function compareThem($a, $b) {
$flat_new = call_user_func_array('array_merge', $a);
$flat_old = call_user_func_array('array_merge', $b);
$rm = array();
if($flat_new != $flat_old) {
$new_old = array_diff($flat_new, $flat_old);
$old_new = array_diff($flat_old, $flat_new);
$diff = array_merge($new_old, $old_new);
foreach ($diff as $key => $value) {
if(in_array($value, $flat_new) && !in_array($value, $flat_old)) {
$rm[] = array("new"=>true, "left"=>false, "user"=>$value);
} else if(in_array($value, $flat_old) && !in_array($value, $flat_new)) {
$rm[] = array("new"=>false, "left"=>true, "user"=>$value);
}
}
}
return $rm;
}
$new = array("GUILDMASTER" => array("foo"), "OFFICER" => array("bar", "baz"), "MEMBER" => array("foobar", "foobaz"));
$old = array("GUILDMASTER" => array("foo"), "OFFICER" => array("bar", "baz"), "MEMBER" => array("foobar"));
compareThem($new,$old) // will output [{"new":true,"left":false,"user":"foobaz"}]
You can do this. It detects additions, deletions, and modifications:
// your array before the change
$before = ["GUILDMASTER" => ["foo"], "OFFICER" => ["bar","baz"], "MEMBER" => ["foobar","foobaz"]];
// your array after the change (foo was moved from GUILDMASTER to OFFICER)
$after = ["GUILDMASTER" => [], "OFFICER" => ["bar","baz", "foo"], "MEMBER" => ["foobar","foobaz"]];
// create lookup table to check the position a person previously held
$positions_before = [];
foreach($before as $position => $people) {
foreach($people as $person) {
$positions_before[$person] = $position;
}
}
// scan new positions...
$changes = [];
foreach($after as $position => $people) {
foreach($people as $person) {
// track when a new person is added (they wont be in the table)
if(!isset($positions_before[$person])) {
$changes[] = ["user" => $person, "was_found_in" => "DIDNT_EXIST", "now_found_in" => $position];
// track when a change is detected (different value than table)
}elseif($positions_before[$person] != $position) {
$changes[] = ["user" => $person, "was_found_in" => $positions_before[$person], "now_found_in" => $position];
}
// remove this person from the table after parsing them
unset($positions_before[$person]);
}
}
// anyone left in the lookup table is in $before and $after
// so track that they were removed/fired
foreach($positions_before as $person => $position) {
$changes[] = ["user" => $person, "was_found_in" => $position, "now_found_in" => "REMOVED"];
}
print_r($changes);
outputs [user] => foo [was_found_in] => GUILDMASTER [now_found_in] => OFFICER

Php Array key=> value searching

HI I am fairly new to php.
I have an array
$arr = array(0 => array('GID'=>1,'groupname'=>"cat1",'members'=>array(0=>array('mid'=>11,'mname'=>'wwww'),1=>array('mid'=>12,'mname'=>'wswww'))),
1 => array('GID'=>2,'groupname'=>"cat2",'members'=>array(0=>array('mid'=>13,'mname'=>'gggwwww'),1=>array('mid'=>14,'mname'=>'wvvwww'))),
2 => array('GID'=>3,'groupname'=>"cat1",'members'=>array(0=>array('mid'=>15,'mname'=>'wwddsww')),1=>array('mid'=>16,'mname'=>'wwwdddw')));
ie...,I have GID,groupname,mid(member id),mname(member name).I want to insert a new mid and mname into a group if it is already in the array ,if it is not exists then create a new subarray with these elements..I also need to check a member id(mid) is also present.........................I used the code but its not working fine............. if (!empty($evntGroup)) {
foreach ($evntGroup as $k => $group) {
if ($group['GID'] == $group_id) {
foreach($group as $j=> $mem){
if($mem['mid'] == $mem_id){
unset($evntGroup[$k]['members'][$j]['mid']);
unset($evntGroup[$k]['members'][$j]['mname']);
}
else{
$evntGroup[$k]['members'][] = array(
'mid' => $mem_id,
'mname' => $mem_name);
}}
} else {
$evntGroup[] = array(
'GID' => $group_id,
'groupname' => $Group['event_group_name'],
'members' => array(
0 => array(
'mid' => $mem_id,
'mname' => $mem_name
)
)
);
}
}
} else {
$evntGroup[$i]['GID'] = $group_id;
$evntGroup[$i]['groupname'] = $Group['event_group_name'];
$evntGroup[$i]['members'][] = array(
'mid' => $mem_id,
'mname' => $mem_name);
$i++;
}
In the form of a function, the easiest solution will look something like this:
function isGidInArray($arr, $val) {
foreach($arr as $cur) {
if($cur['GID'] == $val)
return true;
}
return false;
}
You've updated your question to specify what you want to do if the specified GID is found, but that's just a trivial addition to the loop:
function doSomethingIfGidInArray($arr, $val) {
foreach($arr as $cur) {
if($cur['GID'] == $val) {
doSomething();
break; //Assuming you only expect one instance of the passed value - stop searching after it's found
}
}
}
There is unfortunately no native PHP array function that will retrieve the same index of every array within a parent array. I've often wanted such a thing.
Something like this will match if GID equals 3:
foreach( $arr as $item ) {
if( $item['GID'] == 3 ) {
// matches
}
}
There is the code
function updateByGid(&$array,$gid,$groupname,$mid,$mname) {
//For each element of the array
foreach ($array as $ii => $elem) {
//If GID has the same value
if ($elem['GID'] == $gid) {
//Insert new member
$array[$ii]['members'][]=array(
'mid'=>$mid,
'mname'=>$mname);
//Found!
return 0;
}
}
//If not found, create new
$array[]=array(
'GID'=>$gid,
'groupname'=>$groupname,
'members'=>array(
0=>array(
'mid'=>$mid,
'mname'=>$mname
)
)
);
return 0;
}

PHP: Count the appearance of particular value in array

I am wondering if I could explain this.
I have a multidimensional array , I would like to get the count of particular value appearing in that array
Below I am showing the snippet of array . I am just checking with the profile_type .
So I am trying to display the count of profile_type in the array
EDIT
Sorry I've forgot mention something, not something its the main thing , I need the count of profile_type==p
Array
(
[0] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => p
[birthyear] => 1978
[is_elite] => 0
)
)
[1] => Array
(
[Driver] => Array
(
[id] => 4
[profile_type] => d
[birthyear] => 1972
[is_elite] => 1
)
)
)
Easy solution with RecursiveArrayIterator, so you don't have to care about the dimensions:
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$counter = 0
foreach ($iterator as $key => $value) {
if ($key == 'profile_type' && $value == 'p') {
$counter++;
}
}
echo $counter;
Something like this might work...
$counts = array();
foreach ($array as $key=>$val) {
foreach ($innerArray as $driver=>$arr) {
$counts[] = $arr['profile_type'];
}
}
$solution = array_count_values($counts);
I'd do something like:
$profile = array();
foreach($array as $elem) {
if (isset($elem['Driver']['profile_type'])) {
$profile[$elem['Driver']['profile_type']]++;
} else {
$profile[$elem['Driver']['profile_type']] = 1;
}
}
print_r($profile);
You may also use array_walk($array,"test") and define a function "test" that checks each item of the array for 'type' and calls recursively array_walk($arrayElement,"test") for items of type 'array' , else checks for the condition. If condition satisfies, increment a count.
Hi You can get count of profuke_type==p from a multi dimensiona array
$arr = array();
$arr[0]['Driver']['id'] = 4;
$arr[0]['Driver']['profile_type'] = 'p';
$arr[0]['Driver']['birthyear'] = 1978;
$arr[0]['Driver']['is_elite'] = 0;
$arr[1]['Driver']['id'] = 4;
$arr[1]['Driver']['profile_type'] = 'd';
$arr[1]['Driver']['birthyear'] = 1972;
$arr[1]['Driver']['is_elite'] = 1;
$arr[2]['profile_type'] = 'p';
$result = 0;
get_count($arr, 'profile_type', 'd' , $result);
echo $result;
function get_count($array, $key, $value , &$result){
if(!is_array($array)){
return;
}
if($array[$key] == $value){
$result++;
}
foreach($array AS $arr){
get_count($arr, $key, $value , $result);
}
}
try this..
thanks

Categories