首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 多維陣列依鍵名快速查詢父鍵與父鍵值的實作技巧

     編輯:PHP 綜合知識

前言

在處理多維陣列時,常會遇到「根據某個鍵名,快速找出其父層鍵名與父層資料」的需求。本文將分享一個由簡單函式演進為完整類別的實作過程,並解決同名鍵衝突的問題。

第一版:簡單索引函式

核心概念是遞迴遍歷陣列,建立「鍵名 → 父鍵名」的一維索引表:

<?php
function indexKey($data, $parent = NULL) {
    $arr = array();
    foreach ($data as $key => $value) {
        $arr[$key] = $parent;
        if (is_array($value)) {
            $arr += indexKey($value, $key);
        }
    }
    return (Array)$arr;
}
?>

輸出範例:

Array
(
    [china] => 
    [name] => china
    [cite] => china
    [beijing] => cite
    [site] => beijing
    [chaoyang] => site
    [xuanwu] => site
    [shanghai] => cite
    [jingan] => site
    [huangpu] => site
)

缺點:若陣列中存在同名鍵(如多個 name),後者會覆蓋前者,導致資料遺失。

第二版:IndexKey 類別(支援同名鍵)

改用類別封裝,索引值改為陣列以儲存多個父鍵:

<?php
class IndexKey {
    private $_arr = array();

    public function __construct($data) {
        $this->_createIndex($data);
    }

    public function printArr() {
        return (Array)$this->_arr;
    }

    public function search($key) {
        return isset($this->_arr[$key]) ? $this->_arr[$key] : NULL;
    }

    private function _createIndex($data, $parent = NULL) {
        foreach ($data as $key => $value) {
            $this->_checkIndex($key, $parent);
            if (is_array($value)) {
                $this->_createIndex($value, $key);
            }
        }
    }

    private function _checkIndex($key, $parent) {
        $index = isset($this->_arr[$key]) ? $this->_arr[$key] : NULL;
        if ($index) {
            if (is_array($index)) {
                array_push($this->_arr[$key], $parent);
            } else {
                $this->_arr[$key] = array($index, $parent);
            }
        } else {
            $this->_arr[$key] = $parent;
        }
    }
}
?>

使用方式:

$index = new IndexKey($arr);
print_r($index->printArr());
echo $index->search('beijing'); // 輸出 cite
echo $index->search('name');    // 輸出 Array ( [0] => china [1] => beijing [2] => shanghai )

第三版:IndexArr 類別(同時取得父鍵值)

進一步強化,索引同時記錄「父鍵名」與「父層完整資料」:

<?php
class IndexArr {
    private $_arr = array();

    public function __construct($data) {
        $this->_createIndex($data);
    }

    public function printArr() {
        return (Array)$this->_arr;
    }

    public function search($key) {
        return isset($this->_arr[$key]) ? $this->_arr[$key]['parent'] : NULL;
    }

    public function parentValue($key) {
        return isset($this->_arr[$key]) ? $this->_arr[$key]['data'] : NULL;
    }

    private function _createIndex($data, $parent = NULL) {
        foreach ($data as $key => $value) {
            $this->_checkIndex($key, $parent, $data);
            if (is_array($value)) {
                $this->_createIndex($value, $key);
            }
        }
    }

    private function _checkIndex($key, $parent, $data) {
        $data = $parent && isset($data[$parent]) ? $data[$parent] : $data;
        !isset($this->_arr[$key]) && $this->_arr[$key] = array('data' => $data, 'parent' => '');
        $index = &$this->_arr[$key]['parent'];
        if (!empty($index)) {
            if (is_array($index)) {
                array_push($index, $parent);
            } else {
                $index = array($index, $parent);
            }
        } else {
            $index = $parent;
        }
    }
}
?>

現在可以一次取得父鍵名與父層資料:

$index2 = new IndexArr($arr);
echo $index2->search('beijing');       // cite
print_r($index2->parentValue('beijing')); // 取得 cite 節點完整陣列

總結

  • 版本一:簡單快速,但不支援同名鍵。
  • 版本二:解決同名鍵衝突,可查詢所有父鍵名。
  • 版本三:進一步提供父層資料存取,適合需要同時取得鍵名與值的場景。

完整原始碼可下載:php_arr.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved