【问题标题】:Reference PHP array by multiple indexes通过多个索引引用 PHP 数组
【发布时间】:2011-05-23 06:15:41
【问题描述】:

这可能是某种奇怪的更长的捷径,如果我在这个思路上弄错了,请纠正我......

我有一个数据矩阵,如下所示:

unique_id | url | other random data...
unique_id | url | other random data...
unique_id | url | other random data...

我希望能够通过它的 url 或它的 unique_id 来引用一个项目 - 有没有一种奇特的方法可以做到这一点?

我想作弊的解决方案是只制作两个数组,但我想知道是否有更好的方法。

【问题讨论】:

  • 不是,不是。只需制作两个数组。开销很小(嗯,取决于你的数组有多大)。
  • 数组中的“随机数据”是否需要修改? unique_id 和 URL 有可能发生冲突吗?
  • 不要重复“其他随机数据”(“DRY”概念)。最简洁的解决方案是使用一个数组将unique_id 映射到other random data,然后使用第二个数组将url 映射到unique_id。这就是unique_ids 的目的:提供一个简洁高效的“句柄”来表示给定的数据记录(行)。

标签: php arrays multidimensional-array


【解决方案1】:

试试这样的:

function selectByIdOrURL($array, $data) {
    foreach($array as $row) {
       if($row['unique_id'] == $data || $row['url'] == $data) return $row;
    }
    return NULL;
}

$array = array(
           array('unique_id' => 5, 'url' => 'http://blah.com'),
           array('unique_id' => 3, 'url' => 'http://somewhere_else.com')
         );
$found = selectByIdOrURL($array, 5); //array('unique_id' => 5, 'url' => 'http://blah.com')
$nfound = selectByIdOrURL($array, 10); //NULL

【讨论】:

  • 是迭代数据的唯一方法吗?我想这不是什么大不了的事,但我真的很好奇你是否可以有多个数组索引(一般来说)
  • @Bob,不,没有办法为数组设置多个索引。
  • 一般来说,没有。最快的方法(访问时间)是有两个数组,一个以 unique_id 作为键,另一个以 URL,并且都以所有数据作为值。雅各布的答案将使用稍微少一点的内存,但每次引用某些东西时都需要迭代整个数组;我的方法会使用更多的内存,但会更快地检索结果。
  • 真可惜……我想只是迭代它还不错
  • 任何花哨的解决方案都会在幕后进行迭代。
【解决方案2】:

我能想到的不涉及为每次搜索迭代数组的唯一方法(参见 Jacob 的回答)是将每个项目的引用存储在两个数组中。

编辑:由于 URL 和 ID 不能冲突,它们可能存储在同一个引用数组中(感谢 Matthew)

$items; // array of item objects
        // Use objects so they're implicitly passed by ref

$itemRef = array();

foreach ($items as $item) {
    $itemRef[$item->unique_id] = $item;
    $itemRef[$item->url] = $item;
}

// find by id
$byId = $itemRef[$id];

// find by url
$byUrl = $itemRef[$url];

您可以使用实现getById()getByUrl() 的集合类很好地封装它。在内部,它可以根据需要将引用存储在尽可能多的数组中。

当然,您在这里实际上要做的是创建索引结果集,最好留给数据库管理系统。

【讨论】:

  • 另外,如果您愿意,您可以将它们放在同一个数组中(例如$items)。这可能有点令人困惑,但 Bob 说键不能碰撞。
  • 哦,这很有趣。它们不会发生冲突,但从漏洞的角度来看似乎有点可怕(例如,强制使用 url 而不是 unique_id 的查找)。不过技术不错
  • @Bob 类似于使用fetch_both 方法检索数据库记录,结果同时包含数字和字符串索引。说到索引,如果这些数据确实来自数据库,那么最好将索引应用于 ID 和 url 字段并进行单次提取以检索指定的记录。
  • @MatthewFlaschen - 您可以将它们放在同一个数组中,但如果有第二个数组将url 映射到unique_id 会更简洁。将不同的概念分开。
【解决方案3】:

对象肯定是最简单的方法吗?

class Item {
    public $unique_url;
    public $url;
    public $other_data;

    public function __construct($unique_url, $url, $other_data)
    {
        $this->unique_url = $unique_url;
        $this->url = $url;
        $this->other_data = $other_data;
    }
}



class ItemArray {
    private $items = array();

    public function __construct()
    {
    }

    public function push(Item $item)
    {
        array_push($items, $item); //These may need to be reversed
    }

    public function getByURL($url)
    {
        foreach($items as $item)
        {
            if($item->url = $url)
            {
                return $item;
            }
        }
    }

    public function getByUniqueURL($url)
    {
        foreach($items as $item)
        {
            if($item->unique_url = $unique_url)
            {
                return $item;
            }
        }
    }

}

然后使用它

$itemArray = new ItemArray();
$item = new Item("someURL", "someUniqueURL","some other crap");
$itemArray->push($item);

$retrievedItem = $itemArray->getItemByURL("someURL");

由于创建对象,这种技术有一点额外的开销,但除非你正在做疯狂的行数,否则就可以了。

【讨论】:

    【解决方案4】:

    看来您的奇特解决方案仅在 PHP 5.5 中可用。 您可以结合使用 array_searcharray_column 在一行代码中获取您的条目:

    $items = [
        [
         'unique_id' => 42,
         'url' => 'http://foo.com'
        ],
        [
         'unique_id' => 57,
         'url' => 'http://bar.com'
        ],
        [
         'unique_id' => 36,
         'url' => 'http://example.com'
        ],
    
    ];
    
    $bar = $entries[array_search(57, array_column($items, 'unique_id'))];
    
    var_dump($bar);
    
    //outputs
    array (size=2)
        'unique_id' => int 57
        'url' => string 'http://bar.com' (length=14)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 2018-05-02
      • 1970-01-01
      相关资源
      最近更新 更多