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....
}
}
}
Related
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));
I tried to get array of keys of searched element`s key in multidimensional array. For example, my initial array is:
$f['Kitchen']['Dishes']['Mantovarka']=3;
$f['Kitchen']['Dishes']['Castrool']=91;
$f['Kitchen']['Dishes']['Separator']=10;
$f['Kitchen']['Product']=18;
$f['Kitchen']['Textile']=19;
$f['Kitchen']['Blue things One']['Juicemaker']=25;
$f['Kitchen']['Blue things One']['Freegener']=13;
$f['Kitchen']['Blue things']['Microwave']=4;
$f['Kitchen']['Blue things']['Iron']=24;
If I try to get array of keys for 'Separator' key with this function:
$index=0; $array =[];
function getArrayOfkeys($needle, $haystack,$original,$array,$index) {
$index++;
$exists = false;
if(is_array($haystack)){
foreach ($haystack as $key => $val) {
$array[$index]=$key;
if($key == $needle){
$exists = true;
break;
}elseif(is_array($val)){
return getArrayOfkeys($needle, $val,$original,$array,$index);
}
}
}else{
$index--;
}
if($exists==true){
return $array;
}
else{
// I need here logic!!!
}
}
it returns me:
[
1 => 'Kitchen'
2 => 'Dishes'
3 => 'Separator'
]
it is fine!
But when I try to get array of keys of 'Juicemaker' or 'Iron' or 'Product'. It is not working, because I can`t call my getArrayOfkeys() function after element:
$f['Kitchen']['Dishes']['Separator']=10;
How can I call again after abovementioned element?
I want to get for 'Juicemaker' key ['Kitchen', 'Blue things One', 'Juicemaker'].
For 'Product' key ['Kitchen','Product'].
For 'Iron' key ['Kitchen', 'Blue things','Iron']
My function seems to me very unoptimized, help me, please, with optimize it.
Please try this function:
function findKeyPath($arr, $key, $path = '') {
foreach($arr as $k => $value) {
if(is_array($arr[$k])) {
$ret = findKeyPath($arr[$k], $key, $path.$k.',');
if(is_array($ret)) {
return $ret;
}
}else if($k == $key) {
return explode(',', $path.$key);
}
}
return null;
}
print_r(findKeyPath($f, 'Juicemaker'));
//Output: Array ( [0] => Kitchen [1] => Blue things One2 [2] => Juicemaker )
Demo: https://3v4l.org/YJD7q
I hope this will help you.
Okay, so I need to dynamically dig into a JSON structure with PHP and I don't even know if it is possible.
So, let's say that my JSON is stored ad the variable $data:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
}
}
So, to access the value of value_actionsBla, I just do $data['actions']['bla']. Simple enough.
My JSON is dynamically generated, and the next time, it is like this:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
'bli':{
'new': 'value_new'
}
}
}
Once again, to get the new_value, I do: $data['actions']['bli']['new'].
I guess you see the issue.
If I need to dig two levels, then I need to write $data['first_level']['second_level'], with three, it will be $data['first_level']['second_level']['third_level'] and so on ...
Is there any way to perform such actions dynamically? (given I know the keys)
EDIT_0: Here is an example of how I do it so far (in a not dynamic way, with 2 levels)
// For example, assert that 'value_actionsBla' == $data['actions']['bla']
foreach($data as $expected => $value) {
$this->assertEquals($expected, $data[$value[0]][$value[1]]);
}
EDIT_1
I have made a recursive function to do it, based on the solution of #Matei Mihai:
private function _isValueWhereItSupposedToBe($supposedPlace, $value, $data){
foreach ($supposedPlace as $index => $item) {
if(($data = $data[$item]) == $value)
return true;
if(is_array($item))
$this->_isValueWhereItSupposedToBe($item, $value, $data);
}
return false;
}
public function testValue(){
$searched = 'Found';
$data = array(
'actions' => array(
'abort' => '/abort',
'next' => '/next'
),
'form' => array(
'title' => 'Found'
)
);
$this->assertTrue($this->_isValueWhereItSupposedToBe(array('form', 'title'), $searched, $data));
}
You can use a recursive function:
function array_search_by_key_recursive($needle, $haystack)
{
foreach ($haystack as $key => $value) {
if ($key === $needle) {
return $value;
}
if (is_array($value) && ($result = array_search_by_key_recursive($needle, $value)) !== false) {
return $result;
}
}
return false;
}
$arr = ['test' => 'test', 'test1' => ['test2' => 'test2']];
var_dump(array_search_by_key_recursive('test2', $arr));
The result is string(5) "test2"
You could use a function like this to traverse down an array recursively (given you know all the keys for the value you want to access!):
function array_get_nested_value($data, array $keys) {
if (empty($keys)) {
return $data;
}
$current = array_shift($keys);
if (!is_array($data) || !isset($data[$current])) {
// key does not exist or $data does not contain an array
// you could also throw an exception here
return null;
}
return array_get_nested_value($data[$current], $keys);
}
Use it like this:
$array = [
'test1' => [
'foo' => [
'hello' => 123
]
],
'test2' => 'bar'
];
array_get_nested_value($array, ['test1', 'foo', 'hello']); // will return 123
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;
}
Given an array like
$clusters = array(
"clustera" => array(
'101',
'102',
'103',
'104'
),
"clusterb" => array(
'201',
'202',
'203',
'204'
),
"clusterc" => array(
'301',
'302',
'303',
'304'
)
);
How can I search for a server (e.g. 202) and get back its cluster? i.e. search for 202 and the response is "clusterb" I tried using array_search but it seems that is only for monodimensional arrays right? (i.e. complains that second argument is the wrong datatype if I give it $clusters)
$search=202;
$cluster=false;
foreach ($clusters as $n=>$c)
if (in_array($search, $c)) {
$cluster=$n;
break;
}
echo $cluster;
$arrIt = new RecursiveArrayIterator($cluster);
$server = 202;
foreach ($arrIt as $sub){
if (in_array($server,$sub)){
$clusterSubArr = $sub;
break;
}
}
$clusterX = array_search($clusterSubArr, $cluster);
function array_multi_search($needle,$haystack){
foreach($haystack as $key=>$data){
if(in_array($needle,$data))
return $key;
}
}
$key=array_multi_search(202,$clusters);
echo $key;
$array=$clusters[$key];
Try using this function. It returns the key of the $needle(202) in the immediate child arrays of $haystack(cluster). Not tested, so let me know if this works
function getCluster($val) {
foreach($clusters as $cluster_name => $cluster) {
if(in_array($val, $cluster)) return $cluster_name;
}
return false;
}