Как использовать строку в качестве пути индекса массива для получения значения?
скажем, у меня есть массив, например:
Array
(
[0] => Array
(
[Data] => Array
(
[id] => 1
[title] => Manager
[name] => John Smith
)
)
[1] => Array
(
[Data] => Array
(
[id] => 1
[title] => Clerk
[name] =>
(
[first] => Jane
[last] => Smith
)
)
)
)
Я хочу иметь возможность построить функцию, которую я могу передать строку, которая будет действовать как путь индекса массива и возвращать соответствующее значение массива без использования eval()
. Это возможно?
function($indexPath, $arrayToAccess)
{
// $indexPath would be something like [0]['Data']['name'] which would return
// "Manager" or it could be [1]['Data']['name']['first'] which would return
// "Jane" but the amount of array indexes that will be in the index path can
// change, so there might be 3 like the first example, or 4 like the second.
return $arrayToAccess[$indexPath] // <- obviously won't work
}
10 ответов
вы можете использовать массив как путь (слева направо), а затем рекурсивную функцию:
$indexes = {0, 'Data', 'name'};
function get_value($indexes, $arrayToAccess)
{
if(count($indexes) > 1)
return get_value(array_slice($indexes, 1), $arrayToAccess[$indexes[0]]);
else
return $arrayToAccess[$indexes[0]];
}
немного позже, но... надежда помогает кому-то:
// $pathStr = "an:string:with:many:keys:as:path";
$paths = explode(":", $pathStr);
$itens = $myArray;
foreach($paths as $ndx){
$itens = $itens[$ndx];
}
теперь itens является частью массива, который вы хотели.
[] ' s
Labs
Это старый вопрос, но на него ссылались, поскольку этот вопрос возникает часто.
есть рекурсивные функции, но я использую ссылку:
function array_nested_value($array, $path) {
$temp = &$array;
foreach($path as $key) {
$temp =& $temp[$key];
}
return $temp;
}
$path = array(0, 'Data', 'Name');
$value = array_nested_value($array, $path);
попробуйте следующее, где $indexPath отформатирован как путь к файлу, т. е.
'<array_key1>/<array_key2>/<array_key3>/...'.
function($indexPath, $arrayToAccess)
{
$explodedPath = explode('/', $indexPath);
$value =& $arrayToAccess;
foreach ($explodedPath as $key) {
$value =& $value[$key];
}
return $value;
}
например, используя данные из вопроса, $indexPath = '1/Data/name / first' вернет $value = Jane.
function($indexPath, $arrayToAccess)
{
eval('$return=$arrayToAccess'.$indexPath.';');
return $return;
}
вы должны проанализировать строку indexPath. Выберите какой-нибудь разделитель (например "."), читать текст до ".- это будет первый ключ, потом читай "отдых до следующего", это будет следующий ключ. Делайте это до тех пор, пока не будет больше точек.
вы Кен храните ключ в массиве. Сделайте цикл foreach в этом массиве, чтобы получить элемент seeked.
вот один из способов выполнить работу, если синтаксический анализ строк-это то, как вы хотите пойти.
$data[0]["Data"]["stuff"] = "cake";
$path = "[0][\"Data\"]['stuff']";
function indexPath($path,$array){
preg_match_all("/\[['\"]*([a-z0-9_-]+)['\"]*\]/i",$path,$matches);
if(count($matches[1]) > 0) {
foreach ($matches[1] as $key) {
if (isset($array[$key])) {
$array = $array[$key];
} else {
return false;
}
}
} else {
return false;
}
return $array;
}
print_r(indexPath($path,$data));
на preg_match_all
, велоспорт через сопоставленные результаты даст вам близко к результату, который вы хотели. Вы должны быть осторожны со всеми стратегиями, перечисленными здесь потерянную информацию. Например, вы должны придумать какой-то способ убедиться, что 55 остается как тип int и не анализируется как строка типа.
В дополнение к AbraCadaver:
function array_nested_value($array, $path) {
foreach($path as $key) {
$array = $array[$key];
}
return $array;
}
$path = array(0, 'Data', 'Name');
$value = array_nested_value($array, $path);
можно использовать
function get_array_value($array=array(), $path=array()){
foreach($path as $key) {
if(isset($array[$key])){
$array=$array[$key];
}
else{
$array=NULL;
break;
}
}
return $array;
}
function custom_isset($array=array(), $path=array()){
$isset=true;
if(is_array($array)&&is_null(get_array_value($array, $path))){
$isset=false;
}
return $isset;
}
function is($array=array(), $path=array()){
$is=false;
if(is_array($array)){
$array_value=get_array_value($array, $path);
if(is_bool($array_value)){
$is=$array_value;
}
}
return $is;
}
пример
$status=[];
$status['updated']=true;
if(is($status,array('updated'))){
//do something...
}
ресурсы
Если вы уже знаете точный элемент массива, который вы вытаскиваете, зачем писать функцию для этого? Что случилось с just
$array[0]['data']['title']