【问题标题】:Search value in multidimension array and keep keys association在多维数组中搜索值并保持键关联
【发布时间】:2014-10-23 07:38:16
【问题描述】:

我有这个数组是从 web 服务的 xml 转换而来的。我在这个数组中有 500 个项目。 我想搜索任何值并返回所有找到的具有键关联的数组项(类似于数据库选择查询)。所以如果我搜索 'dummy' 那么它应该返回这个数组的第一项。

大批 ( [12.12.2014] => 数组 ( [7] => 数组 ( [id] => 1672 [日期] => 12.12.2014 [描述] => 拉米虚拟数据 [房间] => 豪华 [类型] => 花园 [从] => 17:00 [到] => 17:45 [资产] => 数组 ( [资产] => 数组 ( [0] => 数组 ( [数字] => 5275 [详细] => 初级 ) [1] => 数组 ( [数字] => 19 [详细] => 二级 ) ) ) [参考] => 数组 ( [参考] => 数组 ( [人号] => 479470 [类型] => 工人 [名称] => 大卫 [部门] => 销售 [cv] => 数组 ( [pdetails] => 稍后关注 ) [个人资料] => 真 ) ) ) ) [13.12.2014] => 数组 ( [17] => 数组 ( [id] => 1672 [日期] => 13.12.2014 [描述] => 棕狐跳跃 [房间] => 星星 [类型] => 城市 [从] => 17:00 [到] => 17:45 [资产] => 数组 ( [资产] => 数组 ( [数字] => 5275 [详细] => 素数二 ) ) [参考] => 数组 ( [参考] => 数组 ( [人号] => 479470 [类型] => 经理 [名称] => 阿尔伯特 [部门] => 采购 [cv] => 数组 ( [pdetails] => 稍后关注 ) [个人资料] => 真 ) ) ) ) )

我尝试stripos 在数组值和基于in_array 的函数中搜索字符串,但结果不正确或键关联未维护。

我无法找到维护 key->value 的方法。

函数搜索($array, $key, $value) { $结果 = 数组(); if (is_array($array)) { if (isset($array[$key]) && $array[$key] == $value) $结果[] = $数组; foreach ($array 作为 $subarray) $results = array_merge($results, search($subarray, $key, $value)); } 返回$结果; }

这可能是您见过的最糟糕的功能,但它可以完成工作。如果有人可以使其递归(数组可能更深)。

函数 search_in_multi_array($srchvalue, $array) { $foundkey = ''; if (is_array($array) && count($array) > 0) { foreach($array as $pkey => $pvalue) { foreach($pvalue as $ckey => $cvalue) { if (is_array($cvalue) && count($cvalue) > 0) { if(in_array($srchvalue,$cvalue)) { $foundkey[$pkey][$ckey] = $cvalue; } foreach($cvalue 作为 $dkey => $dvalue) { if(!is_array($dvalue)) { $pos = stripos($dvalue, $srchvalue); 如果 ($pos !== 假) { $foundkey[$pkey][$ckey] = $cvalue; } } } } } } } 返回$foundkey; }

函数调用 - $needle = '狐狸'; search_in_multi_array($needle, $my_array); 这是输出

大批 ( [13.12.2014] => 数组 ( [17] => 数组 ( [id] => 1672 [日期] => 13.12.2014 [描述] => 棕狐跳跃 [房间] => 星星 [Type1] => 城市 [从] => 17:00 [到] => 17:45 [资产] => 数组 ( [资产] => 数组 ( [数字] => 5275 [详细] => 素数二 ) ) [参考] => 数组 ( [参考] => 数组 ( [人号] => 479470 [Type1] => 经理 [名称] => 阿尔伯特 [部门] => 采购 [cv] => 数组 ( [pdetails] => 稍后关注 ) [个人资料] => 1 ) ) ) ) )

【问题讨论】:

  • 你必须展示你尝试过的东西
  • 给定数组的预期输出是什么。举个例子
  • 这显然是一个很好的递归例程的例子。 :-) 但是,是的,向你展示你所拥有的和你期望的输出。

标签: php arrays multidimensional-array


【解决方案1】:

您可以使用 array_search() 函数来查看数组值。但是array_search 只查找一维数组。

由于你有一个多维数组,你可以编写自定义递归函数在数组中递归搜索

function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
    $current_key=$key;
    if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
        return $current_key;
    }
}
return false;
}

但请注意,使用 array_search() 是一种更简单的方法,但不是优化的函数。这意味着如果您更关心内存利用率,那么我也会另外建议。

  • 创建一个新数组,比如“字典”并将它们存储为 $dictonary[<key-searched>] = array('12.12.2014', '13.12.2014')
  • 所以你只处理一次,然后缓存它们
  • 所以下次你想再次搜索相同的键时,你可以先检查该键是否存在于字典中。如果存在则从那里返回,否则使用 array_search 并将结果缓存在字典中

通过键值搜索总是比在多维数组中搜索更容易。

【讨论】:

  • 感谢您的努力。但是这个函数只提供顶级密钥,所以如果我搜索 'garden' ,我只会得到 12.12.2014
  • 但这不正是您所要求的吗? “所以如果我搜索'dummy',那么它应该返回这个数组的第一项。” - 请求的“这个数组的第一项”只是$myArray['12.12.2014'],不是吗?
【解决方案2】:

我制作了一个简单的例程,它将提取您要查找的数组中的值:

function search_keys($needle,$haystack)
{
  foreach($haystack as $key => $value)
  {
    if (is_array($value)) $output[$key] = search_keys($needle,$value);
    else if (strpos($value,$needle) !== FALSE) $output[$key] = $value;
  }
  return isset($output) ? $output : NULL; // prevent warning
}

echo '<pre>';
print_r(search_keys('garden',$data));
echo '</pre>';

这将返回“花园”为:

Array
(
    [12.12.2014] => Array
        (
            [7] => Array
                (
                    [Type] => garden
                )

        )

)

您可以进一步处理此函数的输出,或根据需要更改函数。

【讨论】:

    【解决方案3】:

    您可能希望查看 XPath 以针对“原始”XML 运行查询,例如,请参阅 DOMXPath

    /myRootTag/someDayTag[.//text()[contains(.,'MY_SEARCH_VALUE')]] 之类的东西应该可以解决问题,选择并返回 myRootTag 下方的所有 someDayTag XML 元素,这些元素在任何子节点中都有文本 MY_SEARCH_VALUE

    【讨论】:

    • 没有XML函数就没有解决方案吗?
    • 我确信还有其他解决方案,但如果您只需要从 XML 文档中提取特定值/子结构,那么使用单个 XPath 查询而不是几十个查询应该更容易和简洁将 XML 转换为数组并手动搜索树的代码行数。
    猜你喜欢
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    相关资源
    最近更新 更多