I have the following array:
$array = Array(
"0" => Array (
"id" => 1081,
"name" => "John"
),
"1" => Array (
"id" => 1082,
"name" => "Matt"
),
"2" => Array (
"id" => 1083,
"name" => "Roger"
)
);
Is there anyway I can get name if I only know the id but without having to iterate through the array?
For PHP >= 5.5.0:
$id = 1082;
$result = array_column($array, 'name', 'id')[$id];
As Barmar points out, to get an array that is easy to use with id as the index:
$id = 1082;
$result = array_column($array, 'name', 'id');
echo $result[$id];
You can make an associative array that refers to the same elements, then use that:
function make_assoc(&$array, $keyname) {
$new_array = array();
foreach ($array as &$elt) {
$new_array[$elt[$keyname]] = $elt;
}
return $new_array;
}
$assoc_array = make_assoc($array, 'id');
Now you can use $assoc_array[1083] to access the third item in the original array. And since this returns an array of references, modifying that will also modify the element of the original array.
You can use array_map to search into your array if your PHP < 5.5.0 and you don't have array_column:
<?php
$array = Array(
"0" => Array (
"id" => 1081,
"name" => "John"
),
"1" => Array (
"id" => 1082,
"name" => "Matt"
),
"2" => Array (
"id" => 1083,
"name" => "Roger"
)
);
$find = 1082;
$value = '';
$arr = array_map(function($n) use ($find, &$value) {if ($n['id'] == $find) $value = $n['name']; }, $array);
print_r($value);
?>
Related
There are 2 arrays Say
1. Groups
$groups = array("user", "account", "client")
2. Results
$results = array(
0 => array(
"user" => "U1",
"account" => "A1",
"client" => "C1"
),
1 => array(
"user" => "U1",
"account" => "A2",
"client" => "C1"
),
0 => array(
"user" => "U1",
"account" => "A3",
"client" => "C1"
),
0 => array(
"user" => "U1",
"account" => "A2",
"client" => "C2"
),
0 => array(
"user" => "U1",
"account" => "A1",
"client" => "C4"
),
0 => array(
"user" => "U1",
"account" => "A1",
"client" => "C5"
),
0 => array(
"user" => "U1",
"account" => "A2",
"client" => "C5"
)
) ;
I want following OUTPUT
$output = array(
"U1" => array(
"A1" => array(C1,C4,C5),
"A2" => array(C1,C2,C5),
"A3" => array(C1)
)
);
The Groups array values are dynamic and may be any order. I want output in order the first value of groups array is the parent element of Output array and second value of group array is the child of parent Output array and so on.
I hope you are using PHP greater or equal to 5.6. There we have ... (splat operator) that will come really handy:
$output = [];
array_map(function (...$keys) use (&$output) {
// Pop the last key, because it is actually a value.
$value = array_pop($keys);
// Prepare "element" to assign the value to using keys and references.
$element = &$output;
while($key = array_shift($keys)) {
if (!isset($element[$key])) {
$element[$key] = [];
}
$element = &$element[$key];
}
$element[] = $value;
}, ...array_map(function ($group) use ($results) {
return array_column($results, $group);
}, $groups));
Here is working demo.
In short, we take advantage of the ability of array_map to take any number of arrays as arguments and traverse them kinda parallelly.
Simply make a foreach loop like this
$new = array();
foreach($results as $key=>$value){
$new[$value["user"]][$value["account"]][] = $value["client"];
}
print_r($new);
live demo : https://eval.in/857969
Using $groups : https://eval.in/857970
$new = array();
foreach($results as $key=>$value){
$new[$value[$groups[0]]][$value[$groups[1]]][] = $value[$groups[2]];
}
Example for multiple user's : https://eval.in/857973
Update
For dynamic groups array : You can use eval if you are not interacting user input here. : https://eval.in/858306
I have array inside array:
{
"0" => array("key" => "code", "id" => "4", "value" => "yes"),
"1" => array("key" => "parameter", "id" => "4", "value" => "0"),
"2" => array("key" => "code", "id" => "5", "value" => "no"),
etc...
}
This is what I want to do: I want to have one dimension array in which key would be "id" and value would be "value". However, I need to filter out entries whose key is "parameters". So, in this example, the final array should look like this:
{
"4" => "yes",
"5" => "no"
}
I just can't seem to figure out how to do this. Could you please help me a bit? I tried writing this foreach inside foreach but I just can't wrap my head around how to filter data.
foreach ($settings AS $key => $value) {
$id = null;
$value = null;
foreach ($value AS $key2 => $value2) {
// No idea how to filter out uneccesary entries and save the correct ones
}
$finalArray[$id] = $value;
}
This should do it :
$finalArray = array();
foreach ($settings as $setting) {
if ($setting['key'] != 'parameter') {
$finalArray[$setting['id']] = $setting['value'];
}
}
Assuming all your entries have keys 'key', 'id' and 'value'.
use array_column and array_filter like this, if you want to filter more keys add them to out_keys array :
<?php
$array = [
["key" => "code", "id" => "4", "value" => "yes"],
["key" => "parameter", "id" => "4", "value" => "0"],
["key" => "code", "id" => "5", "value" => "no"]
];
$out_keys = ['parameter'];
$result = array_column(array_filter($array, function($item) use($out_keys) {
return !in_array($item['key'], $out_keys);
}), 'value', 'id');
echo "<pre>";
print_r($result);
output:
Array
(
[4] => yes
[5] => no
)
Assuming $data is your starting array, the code below will output what you want in $result
$result = [];
foreach(array_filter($data, function($el){return $el['key']!='parameter';}) as $el){
$result[$el['id']] = $el['value'];
}
Live demo
For example a multidimensional array like an example below
$arr = array(
[H1] => array(
"name" => "A"
"title" => "T1"
)
[H2] => array(
"name" => "B"
"title" => "B1"
)
)
Let's say I would like to search name which equals to A in $arr and if it's matched, the searching should return the key which is H1
How can I do that in php ?
I tried array_keys($arr, "A") but it returns me with an array instead of the key.
This may help -
$arr = array(
'H1' => array(
"name" => "A",
"title" => "T1",
),
'H2' => array(
"name" => "B",
"title" => "B1",
)
);
// Generate a new array with 'keys' and values in 'name'
$new = array_combine(array_keys($arr), array_column($arr, 'name'));
// Search in that new array
$search = array_search('A', $new);
var_dump($search);
Output
string(2) "H1"
Demo
Another simple way would be -
$serach= false;
foreach($arr as $key => $val) {
if($val['name'] == 'A') {
$search= $key;
break;
}
}
var_dump($search);
I'm trying to manipulate an associative multidimensional array. I've extracted the keys from an array that I want to apply to another's values . . .
These are the keys that I've extracted in another function
$keys = array (
"id" => "id",
"addr_street_num" => "addr_street_num",
"addr_street" => "addr_street",
"price" => "price",
"days" =>"days",
"state" => Array
(
"id" => "id",
"name" => "name"
),
"city" => Array
(
"id" => "id",
"web_id" => "web_id",
"name" => "name"
)
);
This array has the values I'd like to combine together
$vals = array (
"0" => "830680",
"1" => "20",
"2" => "Sullivan Avenue",
"3" => "333000",
"4" => "12",
"5" => Array
(
"0" => "4",
"1" => "Maryland",
),
"6" => Array
(
"0" => "782",
"1" => "baltimore",
"2" => "Baltimore",
)
);
When I try to do array_combine($keys, $val);
I get 2 Notices about Array to string conversion
I guess array_combine only works on one dimensional arrays, any ideas on how to approach this?
If $keys was modified could it be combined with the values - problem is the shape of $keys is what I want to end up with?
It can be done recursively.
function combine_recursive($keys, $values) {
$result = array();
$key = reset($keys);
$value = reset($values);
do {
if (is_array($value)) {
$result[key($keys)] = combine_recursive($key, $value);
} else {
$result[key($keys)] = $value;
}
$value = next($values);
} while ($key = next($keys));
return $result;
}
This works for me with your example arrays. I'm sure this will give you all kinds of weird results/errors if the array structures are different from each other at all.
I want to just store in result values from key 'code' instead of all including 'name' and 'id'
Here is the code:
<?php
$array = array(
array(
"name" => "a",
"code" => "416",
"id" => "a1"
),
array(
"name" => "a",
"code" => "522",
"id" => "a2"
),
array(
"name" => "b",
"code" => "580",
"id" => "b1"
)
);
$counts = array_count_values(
array_map(function (array $entry) { return $entry['name']; }, $array)
// or array_column($array, 'name') in PHP 5.5+
);
$uniqueNames = array_keys(
array_filter($counts, function ($count) { return $count == 1; })
);
$result = array_filter($array, function (array $entry) use ($uniqueNames) {
return in_array($entry['name'], $uniqueNames);
});
print_r($result);
Try this to see the result : http://3v4l.org/32JUL#v530
What I want is: store "code" : "580" only instead of all sets.
I improved this one, because there might be possibility to get more ['code'] values with unique ['name'] , this would not be in best fit here. I would apply a simple foreach to get desired result.
$array = array(
array(
"name" => "a",
"code" => "416",
"id" => "a1"
),
array(
"name" => "a",
"code" => "522",
"id" => "a2"
),
array(
"name" => "b",
"code" => "580",
"id" => "b1"
)
);
$counts = array_count_values(
array_map(function (array $entry) { return $entry['name']; }, $array)
// or array_column($array, 'name') in PHP 5.5+
);
$uniqueNames = array_keys(
array_filter($counts, function ($count) { return $count == 1; })
);
$result = array_filter($array, function (array $entry) use ($uniqueNames) {
return in_array($entry['name'], $uniqueNames);
});
foreach ($result as $res){
$uniqueCodes[] = $res['code'];
}
print_r($uniqueCodes);