Выборка из массива массивов

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
AbS_
Сообщения: 207
Зарегистрирован: 2010.03.27, 14:02

Выборка из массива массивов

Сообщение AbS_ »

имеем:

Код: Выделить всё

$a = array (
       array('id'=>0, ....),
       array('id'=>1, ....),
       array('id'=>0, ....),
       array('id'=>2, ....),
       array('id'=>2, ....),
..........................
       array('id'=>n, ....),
     );
 
Существую ли стандартные способы получить из $a массив $b содержащий элементы с id == 0 ? Или для этого лучше написать свой велосипед?
AbS_
Сообщения: 207
Зарегистрирован: 2010.03.27, 14:02

Re: Выборка из массива массивов

Сообщение AbS_ »

А как в этот самый калбак передать параметр.
имею:

Код: Выделить всё

    
private function getByLvl ($arr, $id = 1) {

        return array_filter($arr, function ($var) {
            return ($var->id == $id);
        });
} 
Проблема в том что array_filter принемает всего 2 параметра, и не понятно, каким образом в него можно передать свои параметры.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Выборка из массива массивов

Сообщение samdark »

А зачем туда передавать свои параметры? Нужно же получить с id == 0?
AbS_
Сообщения: 207
Зарегистрирован: 2010.03.27, 14:02

Re: Выборка из массива массивов

Сообщение AbS_ »

А потом $id == 1 и так далее...
Аватара пользователя
IceDragon
Сообщения: 50
Зарегистрирован: 2010.04.08, 20:02

Re: Выборка из массива массивов

Сообщение IceDragon »

глобальные переменные?
Аватара пользователя
IceDragon
Сообщения: 50
Зарегистрирован: 2010.04.08, 20:02

Re: Выборка из массива массивов

Сообщение IceDragon »

на самом деле я бы выборку дерева доверил бы БД, а точнее - написал бы mysql функцию.

http://dev.mysql.com/tech-resources/art ... -data.html

Код: Выделить всё

Depth of a Sub-Tree
When we need depth information for a sub-tree, we cannot limit either the node or parent tables in our self-join because it will corrupt our results. Instead, we add a third self-join, along with a sub-query to determine the depth that will be the new starting point for our sub-tree:

 SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
 FROM nested_category AS node,
     nested_category AS parent,
     nested_category AS sub_parent,
     (
         SELECT node.name, (COUNT(parent.name) - 1) AS depth
         FROM nested_category AS node,
         nested_category AS parent
         WHERE node.lft BETWEEN parent.lft AND parent.rgt
         AND node.name = 'PORTABLE ELECTRONICS'
         GROUP BY node.name
         ORDER BY node.lft
     )AS sub_tree
 WHERE node.lft BETWEEN parent.lft AND parent.rgt
     AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
     AND sub_parent.name = sub_tree.name
 GROUP BY node.name
 ORDER BY node.lft;


 +----------------------+-------+
 | name                 | depth |
 +----------------------+-------+
 | PORTABLE ELECTRONICS |     0 |
 | MP3 PLAYERS          |     1 |
 | FLASH                |     2 |
 | CD PLAYERS           |     1 |
 | 2 WAY RADIOS         |     1 |
 +----------------------+-------+
This function can be used with any node name, including the root node. The depth values are always relative to the named node. 

Код: Выделить всё

Find the Immediate Subordinates of a Node
Imagine you are showing a category of electronics products on a retailer web site. When a user clicks on a category, you would want to show the products of that category, as well as list its immediate sub-categories, but not the entire tree of categories beneath it. For this, we need to show the node and its immediate sub-nodes, but no further down the tree. For example, when showing the PORTABLE ELECTRONICS category, we will want to show MP3 PLAYERS, CD PLAYERS, and 2 WAY RADIOS, but not FLASH.

This can be easily accomplished by adding a HAVING clause to our previous query:

 SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
 FROM nested_category AS node,
     nested_category AS parent,
     nested_category AS sub_parent,
     (
         SELECT node.name, (COUNT(parent.name) - 1) AS depth
         FROM nested_category AS node,
         nested_category AS parent
         WHERE node.lft BETWEEN parent.lft AND parent.rgt
         AND node.name = 'PORTABLE ELECTRONICS'
         GROUP BY node.name
         ORDER BY node.lft
     )AS sub_tree
 WHERE node.lft BETWEEN parent.lft AND parent.rgt
     AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
     AND sub_parent.name = sub_tree.name
 GROUP BY node.name
 HAVING depth <= 1
 ORDER BY node.lft; 



 +----------------------+-------+
 | name                 | depth |
 +----------------------+-------+
 | PORTABLE ELECTRONICS |     0 |
 | MP3 PLAYERS          |     1 |
 | CD PLAYERS           |     1 |
 | 2 WAY RADIOS         |     1 |
 +----------------------+-------+
If you do not wish to show the parent node, change the HAVING depth <= 1 line to HAVING depth = 1 .

 
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Выборка из массива массивов

Сообщение pirrat »

IceDragon, бд то здесь причем? а если данные пришли из xml например, вы их сначала будете в бд писать что ли?

AbS_, опишите задачу поподробнее, что именно вы хотите получить из исходного массива?
мне кажется что вы не в том направлении идете и тут скорее всего просто нужно сделать из этого списка более удобную структуру(например хеш с ключами-id) и потом работать с ней..
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Выборка из массива массивов

Сообщение pirrat »

Видимо непонятно сказал)
приводим ваш массив к "удобному" виду:

Код: Выделить всё

        $a = array(
            array('id' => 0,), 
            array('id' => 1), 
            array('id' => 0), 
            array('id' => 2), 
            array('id' => 2), 
            array('id' => 1));

        //structure
        $hash = array();

        foreach ($a as $el)
        {
            $hash[$el['id']][] = $el;
        }
        ksort($hash);

        var_dump($hash); 
так тепрь с ним гораздо проще работать...
выбрать все с id=1:
$hash[1];
Последний раз редактировалось pirrat 2010.05.07, 11:38, всего редактировалось 1 раз.
AbS_
Сообщения: 207
Зарегистрирован: 2010.03.27, 14:02

Re: Выборка из массива массивов

Сообщение AbS_ »

Не знаю даже как подробней описать.

Есть массив a вида array('id', ......);
Есть массив b вида array(a1, a2, a3 ...... an);
Задача: выбрать из массива b, массив c, содержащий массивы a с определенным id.

Понятно что можно обойти циклом и посмотреть, я же спрашивал про встроенные средства в php:
например array_filter() частично справляется с такой задачей, но что бы задать определенный id нужно либо пользоваться глобальной переменной либо статик свойством класса, что не есть гуд.
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Выборка из массива массивов

Сообщение pirrat »

Понятно что можно обойти циклом и посмотреть, я же спрашивал про встроенные средства в php:
А цикл это какое то стороннее расширение и не является встроенным средством? :shock:

применим немного ооп магии, с использованием выше упомянутого array_filter

Код: Выделить всё

class SuperFilter {
    private $a;
    private $b;
    function __construct($a,$b)
    {
        $this->a = $a;
        $this->b = $b;
    }

    private function doFilter($var)
    {
        return in_array($var['id'],$this->a);
    }

    public function result()
    {
        return array_filter($this->b,array($this,'doFilter'));
    }
}

$a = array(1,2);
$b = array(
    array('id' => 0,),
    array('id' => 2),
    array('id' => 0),
    array('id' => 2),
    array('id' => 2),
    array('id' => 1));

$filter = new SuperFilter($a,$b);
var_dump($filter->result());
 
вроде не каких НЕ встроенных средств я не использую...

как вариант, можно ещё придумать пару алгоритмов.
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Выборка из массива массивов

Сообщение pirrat »

вариант без заморочек, но с циклом (я понял, что вы и сами можете так, но решение то такое не привели)

Код: Выделить всё

$a = array(1,2);
$b = array(
    array('id' => 0,),
    array('id' => 2),
    array('id' => 0),
    array('id' => 2),
    array('id' => 2),
    array('id' => 1));
$res = array();
foreach($b as $k=> $el)
{
    if(in_array($el['id'],$a))
    $res[$k] = $el;
}
var_dump($res);
 
Ответить