Php Array key=> value searching - php

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;
}

Related

How to I return the first of matching key values?

I have an array that I want to search for a particular value, and then return the key. However, it's likely that there will be multiple matching values. What is the best way to return the key from the first matching value?
$agent_titles = array(
'agent_1' => sales,
'agent_2' => manager, // The key I want to return
'agent_3' => manager,
'agent_4' => director;
);
if (false !== $key = array_search('manager', $agent_titles)) {
return $key;
} else {
return;
}
In this scenario I would want to return 'agent_2'. Thanks in advance!
usage of array_search was best solution
but try write your code simple as possible
$agent_titles=[
'agent_1'=>'sales',
'agent_2'=>'manager',
'agent_3'=>'manager',
'agent_4'=>'director',
];
return array_search('manager',$agent_titles);
public function blahblah($search_value = 'manager') {
$agent_titles = [
'agent_1' => sales,
'agent_2' => manager,
'agent_3' => manager,
'agent_4' => director,
];
foreach($array as $key => $value){
if($value == $search_value){
return $key;
}
}
return false;
}
function getKeyByValue($input, $array) {
foreach ( $array as $key => $value ) {
if ( $input == $value ) {
return $key;
}
}
}
$agent_titles = array(
'agent_1' => 'sales',
'agent_2' => 'manager',
'agent_3' => 'manager',
'agent_4' => 'director'
);
var_dump(getKeyByValue('manager', $agent_titles));

How to append value in array with keys without getting overriding

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;

Get corresponding array values from same index [duplicate]

using array_search in a 1 dimensional array is simple
$array = array("apple", "banana", "cherry");
$searchValue = "cherry";
$key = array_search($searchValue, $array);
echo $key;
but how about an multi dimensional array?
#RaceRecord
[CarID] [ColorID] [Position]
[0] 1 1 3
[1] 2 1 1
[2] 3 2 4
[3] 4 2 2
[4] 5 3 5
for example i want to get the index of the car whose position is 1. How do i do this?
In php 5.5.5 & later versions,
you can try this
$array_subjected_to_search =array(
array(
'name' => 'flash',
'type' => 'hero'
),
array(
'name' => 'zoom',
'type' => 'villian'
),
array(
'name' => 'snart',
'type' => 'antihero'
)
);
$key = array_search('snart', array_column($array_subjected_to_search, 'name'));
var_dump($array_subjected_to_search[$key]);
Output:
array(2) { ["name"]=> string(5) "snart" ["type"]=> string(8) "antihero" }
working sample : http://sandbox.onlinephpfunctions.com/code/19385da11fe0614ef5f84f58b6dae80bd216fc01
Documentation about array_column can be found here
function find_car_with_position($cars, $position) {
foreach($cars as $index => $car) {
if($car['Position'] == $position) return $index;
}
return FALSE;
}
You can try this
array_search(1, array_column($cars, 'position'));
Hooray for one-liners!
$index = array_keys(array_filter($array, function($item){ return $item['property'] === 'whatever';}))[0];
Let's make it more clear:
array_filter(
$array,
function ($item) {
return $item['property'] === 'whatever';
}
);
returns an array that contains all the elements that fulfill the condition in the callback, while maintaining their original array keys. We basically need the key of the first element of that array.
To do this we wrap the result in an array_keys() call and get it's first element.
This specific example makes the assumption that at least one matching element exists, so you might need an extra check just to be safe.
I basically 'recreated' underscore.js's findWhere method which is to die for.
The function:
function findWhere($array, $matching) {
foreach ($array as $item) {
$is_match = true;
foreach ($matching as $key => $value) {
if (is_object($item)) {
if (! isset($item->$key)) {
$is_match = false;
break;
}
} else {
if (! isset($item[$key])) {
$is_match = false;
break;
}
}
if (is_object($item)) {
if ($item->$key != $value) {
$is_match = false;
break;
}
} else {
if ($item[$key] != $value) {
$is_match = false;
break;
}
}
}
if ($is_match) {
return $item;
}
}
return false;
}
Example:
$cars = array(
array('id' => 1, 'name' => 'Toyota'),
array('id' => 2, 'name' => 'Ford')
);
$car = findWhere($cars, array('id' => 1));
or
$car = findWhere($cars, array(
'id' => 1,
'name' => 'Toyota'
));
I'm sure this method could easily reduce LOC. I'm a bit tired. :P
actually all array functions are designed for single dimension array.You always need to keep in mind that you are applying it on single dimension array.
function find_car_with_position($cars, $position) {
for($i=0;$i<count($cars);$i++){
if(array_search($search_val, $cars[$i]) === false){
// if value not found in array.....
}
else{
// if value is found in array....
}
}
}

Combine repeating elements as array in a multidimensional array

I was wondering when working with multimedional arrays, if a certain key is the same, is there a way to combine the contents of other keys into its own array if a certain key is the same?
Something like this:
// name is the same in both arrays
array(
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '1234567'
),
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '5556734'
)
)
into something like this
array(
array(
'name' => 'Pepsi',
'store' => array('Over here', 'Over here'),
'number' => array('1234567', '5556734')
)
)
The defining key is checking if the name element is the same for the other arrays.
You can try a function like this.
function mergeByKey($array,$key){
$tmp_array = array();
foreach ( $array as $k => $row ) {
$merged = false;
foreach ($tmp_array as $k2 => $tmp_row){
if ($row[$key] == $tmp_row[$key]){
foreach ( $row as $k3 => $value ) {
if ($k3 == $key) continue;
$tmp_array[$k2][$k3][] = $value;
$merged = true;
}
}
if ($merged) break;
}
if (!$merged) {
$new_row = array();
foreach ( $row as $k4 => $value ) {
if ($k4 == $key) $new_row[$k4] = $value;
else $new_row[$k4] = array($value);
}
$tmp_array[] = $new_row;
}
}
foreach ( $tmp_array as $t => $row ) {
foreach ( $row as $t2 => $value ) {
if ( count($value) == 1 && $t2 != $key ) $tmp_array[$t][$t2] = $value[0];
}
}
return $tmp_array;
}
passing the array as first parameter and the key as second one.
I'm referencing to your array structure
edited: missed a piece
edited2: if resultin array contains elements with one string, it returns a string and not a array with one element
demo
This function uses a given field name as the grouping identifier and turns all other fields into arrays.
Note that single occurrences of your field name will yield arrays with a single element for the other fields. I wasn't sure whether that's a desirable trait, but just making sure you know ;-)
$arr = array(
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '1234567'
),
array(
'name' => 'Pepsi',
'store' => 'Over here',
'number' => '5556734'
)
);
function mergeArray($array, $column)
{
$res = array();
foreach ($array as $item) {
foreach ($item as $key => $value) {
if ($key === $column) {
$res[$column][$key] = $value;
} else {
$res[$column][$key][] = $value;
}
}
}
return array_values($res);
}
print_r(mergeArray($arr, 'name'));
Demo
Thanks to Gianni Lovece for her answer but I was able to develop a much simpler solution based on this problem. Just plug in the $result_arr to browse through and the $key you want to use as basis and it immediately outputs a multidimensional array with non-repeating values for repeating elements (see example below).
function multiarray_merge($result_arr, $key){
foreach($result_arr as $val){
$item = $val[$key];
foreach($val as $k=>$v){
$arr[$item][$k][] = $v;
}
}
// Combine unique entries into a single array
// and non-unique entries into a single element
foreach($arr as $key=>$val){
foreach($val as $k=>$v){
$field = array_unique($v);
if(count($field) == 1){
$field = array_values($field);
$field = $field[0];
$arr[$key][$k] = $field;
} else {
$arr[$key][$k] = $field;
}
}
}
return $arr;
}
For example, in the sample array for this question, running multiarray_merge($mysample, 'name') returns
array(
'Pepsi' => array(
'name' => 'Pepsi',
'store' => 'Over here', // String: Not an array since values are not unique
'number' => array('1234567', '5556734') // Array: Saved as array since values are unique
)
);

php, long and deep matrix

I have a deep and long array (matrix). I only know the product ID.
How found way to product?
Sample an array of (but as I said, it can be very long and deep):
Array(
[apple] => Array(
[new] => Array(
[0] => Array([id] => 1)
[1] => Array([id] => 2))
[old] => Array(
[0] => Array([id] => 3)
[1] => Array([id] => 4))
)
)
I have id: 3, and i wish get this:
apple, old, 0
Thanks
You can use this baby:
function getById($id,$array,&$keys){
foreach($array as $key => $value){
if(is_array( $value )){
$result = getById($id,$value,$keys);
if($result == true){
$keys[] = $key;
return true;
}
}
else if($key == 'id' && $value == $id){
$keys[] = $key; // Optional, adds id to the result array
return true;
}
}
return false;
}
// USAGE:
$result_array = array();
getById( 3, $products, $result_array);
// RESULT (= $result_array)
Array
(
[0] => id
[1] => 0
[2] => old
[3] => apple
)
The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.
You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')
Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:
<?php
$a = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue'))
),
);
// When true the complete path has been found.
$complete = false;
function get_path($a, $key, $value, &$path = null) {
global $complete;
// Initialize path array for first call
if (is_null($path)) $path = array();
foreach ($a as $k => $v) {
// Build current path being tested
array_push($path, $k);
// Check for key / value match
if ($k == $key && $v == $value) {
// Complete path found!
$complete= true;
// Remove last path
array_pop($path);
break;
} else if (is_array($v)) {
// **RECURSION** Step down into the next array
get_path($v, $key, $value, $path);
}
// When the complete path is found no need to continue loop iteration
if ($complete) break;
// Teardown current test path
array_pop($path);
}
return $path;
}
var_dump( get_path($a, 'id', 3) );
$complete = false;
var_dump( get_path($a, 'id', 2) );
$complete = false;
var_dump( get_path($a, 'id', 5) );
$complete = false;
var_dump( get_path($a, 'keyname', 'keyvalue') );
I tried this for my programming exercise.
<?php
$data = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4))
),
);
####print_r($data);
function deepfind($data,$findfor,$depth = array() ){
foreach( $data as $key => $moredata ){
if( is_scalar($moredata) && $moredata == $findfor ){
return $depth;
} elseif( is_array($moredata) ){
$moredepth = $depth;
$moredepth[] = $key;
$isok = deepfind( $moredata, $findfor, $moredepth );
if( $isok !== false ){
return $isok;
}
}
}
return false;
}
$aaa = deepfind($data,3);
print_r($aaa);
If you create the array once and use it multiple times i would do it another way...
When building the initial array create another one
$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];

Categories