Ссылочный массив PHP по нескольким индексам - PullRequest
6 голосов
/ 10 декабря 2010

Это может быть какой-то странный, более длинный ярлык, и, пожалуйста, поправьте меня, если я ошибаюсь в этом процессе ...

У меня есть матрица данных, которая выглядит следующим образом:

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

Я хочу иметь возможность ссылаться на элемент либо по его URL, либо по уникальному_id - есть ли причудливый способ сделать это?

Полагаю, что обманным решением было бы просто создать два массива, но мне было интересно, есть ли лучший способ.

Ответы [ 4 ]

11 голосов
/ 10 декабря 2010

Единственный способ, которым я могу представить, что не включает итерацию массива для каждого поиска (см. Ответ Джейкоба), это хранить ссылки на каждый элемент в двух массивах.

Редактировать :Поскольку URL-адреса и идентификаторы не могут конфликтовать друг с другом, они могут храниться в одном и том же ссылочном массиве (спасибо Мэтью)

$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().Внутренне он может хранить ссылки в любом количестве массивов, сколько необходимо.

Конечно, здесь вы, по сути, делаете создание индексированных наборов результатов, что лучше оставить системам управления базами данных.

1 голос
/ 15 июня 2016

Похоже, что ваше причудливое решение было доступно только с PHP 5.5 . Вы можете комбинировать использование array_search и array_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)
1 голос
/ 10 декабря 2010

Попробуйте что-то вроде этого:

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
0 голосов
/ 28 сентября 2012

Неужели объект будет легким путем?

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");

Эта техника имеет немного дополнительных накладных расходов из-за создания объекта, но если вы не выполняете безумное количество строк, все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...