【问题标题】:PHP Find value in a multi-dimensional array by keyPHP 通过键查找多维数组中的值
【发布时间】:2015-01-18 11:12:01
【问题描述】:

我从 API 收到一个大型多维数组。我将数组保存到类属性中,然后使用魔法 getter 来伪装数组并让最终用户使用键作为属性 ($class->key ==> $class->data['key'])。

现在我正在处理的数组非常多维,我需要不同“级别”或层上的键。想象一下这个数组有两个分支,有多个层。

我要查找的键通常是顶级的。

我将尝试说明这一点:

Array
    baseKey
        key1
            value1
        key2
            value2
        key3
            subKey1
                value3
            subKey2
                value4
    key4
        value5
    key5
        subKey3
            value6
    key6
        subKey4
            subSubKey1
                value7

我正在寻找一个可以给任何键的函数,包括baseKeykeysubKeysubSubKey,它将返回匹配的第一个键的相应值。

举个例子:

awesomeFindByKey('key2') 
    ==> value2

awesomeFindByKey('subKey4') 
    ==> array('subSubKey1' => 'value7')

awesomeFindByKey('key6') 
    ==> array('subKey4' => array('subSubKey1' => 'value7'))

有这个功能还是我必须自己写一个?有人可能有这样做的功能吗?

我希望这是可以理解的。谢谢。

【问题讨论】:

  • 递归会响吗?
  • 我想知道是否有一个函数可以让我不必 array_map。
  • 您可以编写自己的函数而不使用 array_map,因为它不是那么快。
  • 那会是什么样子? foreach 不递归。那我会用什么?
  • 这个数组是否存储在一个类中?

标签: php arrays


【解决方案1】:

这是非常简单的示例实现:

// sample class
class A {

  // the data array
  protected $data = array();

  // init
  public function __construct($data = null) {
    $this->setData($data);
  }

  // recursive search of a key
  private function searchLayer($key, $layer, $searchKey) {
    // return the layer if we have a match
    if ((string) $key === (string) $searchKey) return $layer;

    // loop the array if we need to go deeper
    if ((array) $layer === $layer) {
        foreach ($layer as $k => $v) {
            // apply recursition
            $result = $this->searchLayer($k, $v, $searchKey);

            // return on match
            if (!empty($result)) return $result;
        }
    }

    // nothing found - recursion ended here
    return null;
  }

  // returns the value of the data array with the given key
  public function getValueByKey($searchKey) {
    echo '<br>search by key: ' . $searchKey . '<br>';

    // check if we have a match
    foreach ($this->data as $key => $layer) {
        // resolve layer
        $result = $this->searchLayer($key, $layer, $searchKey);

        // return on match
        if (!empty($result)) return $result;
    }

    // nothing found
    return null;
  }

  // set the data
  public function setData($data) {
    if ((array) $data === $data) $this->data = $data;
  }

  // possible extension
  public function __get($key) {
    return $this->getValueByKey($key);
  }
}

// create the object of the class 'a'
$a = new A();

// set the data
$a->setData(array(
  'value1',
  'key2' => 'value2',
  'key3' => array(
    'subkey31' => 'value31',
    'subkey32' => 'value32'
  )
));

var_dump($a->getValueByKey('subkey32'));
var_dump($a->subkey32);

输出:string(7) "value32" string(7) "value32"

在这里测试:http://writecodeonline.com/php 只需粘贴代码并点击运行。

编辑

当然,这是一个非常基本的示例 - 您也可以使用一些给定的 php 类,就像其他人已经说过的那样,例如 ArrayAccess

【讨论】:

  • 看起来 $a->subkey32 不起作用。当然 $a->subkey31 也一样。然而,这将是必不可少的。
  • 如果这适合您的目的,您可以接受答案。否则请告诉我你想改变什么。谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-11-28
  • 2014-05-11
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多