PHP объект для сортировки массива по ассоциативному ключу - PullRequest
0 голосов
/ 28 февраля 2019

Доброе утро, я просто потрясен этим, но у php есть более 10 способов сортировки массива, но я не могу найти один для сортировки по требуемому ключу динамически.

Я не могу установить что-то вроденекоторые uksorts, потому что он будет заполнен динамически.Я использую smarty на передней панели (у которого нет функций сортировки массивов), и я пытаюсь создать вызываемую статическую переменную для преобразования и печати отсортированных массивов в одной конкретной точке.

Я применил некоторую логикуи я думаю, что это будет что-то вроде этого.

Smarty:

  {assign var='key' value='category_id'}
  {assign var='direction' value='normal'}
  {assign var='sortedItem' value=''}
    {foreach $object.prop item="item"}
        {sortedItem = Class::arraySortBy($item, $key, $direction)}
        <a href="{$item['link']}">
            {$item['name']}
        </a>
    {foreach}

PHP:

public static function arraySortBy($elemGroup, $sortBy, $direction) {
    if(is_object($elemGroup)){
        $elemGroup =  (array) $elemGroup;
    }
    if ($direction == 'normal') {
        // here is where i want to sort the elemGroup array by the key i want, as the key is product_id and i want to sort by category_id
    } else if ($direction == 'reverse'){
        // here the same but in reverse order
    } else {
       error_log('Direction not properly set.');
    }

    return $elemGroup;
}

Дело в том, что я хочу переупорядочить объекты, но category_id, а затем по product_id IE:

itemA{product_id=1, category_id=1}
itemB{product_id=2, category_id=2}
itemC{product_id=3, category_id=1}
itemE{product_id=4, category_id=1}
itemD{product_id=5, category_id=2} 

Результат:

itemA
itemB
itemC
itemE
itemD

ожидаемый результат

itemA
itemC
itemE
itemB
itemD

Есть ли способ сделать это с помощью функций сортировки PHP или он должен быть пользовательским?

Спасибо

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Почему вы не можете использовать uasort?

function custom_array_sort($arr, $sorts)
{
    // Either pass an array of sorts, or every argument after the first one.
    $sorts = is_array($sorts) ? $sorts : array_slice(func_get_args(), 1);

    uasort($arr, function ($a, $b) use (&$arr, $sorts) {
        for ($i = 0; $i < count($sorts); $i++) {
            if ($a[$sorts[$i]] == $b[$sorts[$i]]) {
                if (isset($sorts[$i + 1])) {
                    $arr = custom_array_sort($arr, array_slice($sorts, 1));
                } else {
                    return 0;
                }
            } else {
                return $a[$sorts[$i]] - $b[$sorts[$i]];
            }
        }
    });

    return $arr;
}

Live демо

Это работает при первом сравнении category_id fields.
Если они совпадают, то мы сравниваем product_id.Вычитание используется для того, чтобы меньшее из product_id s сортировалось перед , чем большее.

Если category_id s не совпадают, то мы выполняем ту же операцию наcategory_id s, как мы делали выше для product_id.


Чтобы реализовать это на ваш взгляд, следуйте этой документации

$smarty->register_function('custom_array_sort', 'custom_array_sort_wrapper');

function custom_array_sort_wrapper($params, &$smarty)
{
    if (empty($params['arr'])) {
        $arr = [];
    } else {
        $arr = $params['arr'];
    }

    if (empty($params['sorts'])) {
        $sorts = [];
    } else {
        $sorts = $params['sorts'];
    }

    return custom_array_sort($arr, $sorts);
}

Это можетзатем использовать их в своих представлениях следующим образом:

{custom_array_sort arr=$object sorts=['category_id', 'product_id']}

Преимущество этой новой реализации заключается в том, что вы можете указать столько столбцов для сортировки, сколько хотите.
Это также означает, что вы можете указатьразные столбцы для сортировки по различным массивам.

Если вы хотите отсортировать по нескольким столбцам, просто добавьте другое имя столбца в массив $sorts.

0 голосов
/ 28 февраля 2019

Вы можете попробовать эту функцию.

function array_sort($array, $on, $order=SORT_ASC){

    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
                asort($sortable_array);
                break;
            case SORT_DESC:
                arsort($sortable_array);
                break;
        }

        foreach ($sortable_array as $k => $v) {
            $new_array[$k] = $array[$k];
        }
    }

    return $new_array;
}

Пример:

Значение массива: -

$item_array = array (
    'itemA' => array('product_id'=>1, 'category_id'=>1), 
    'itemB' => array('product_id'=>2, 'category_id'=>2),
    'itemC' => array('product_id'=>3, 'category_id'=>1),
    'itemD' => array('product_id'=>4, 'category_id'=>1),
    'itemE' => array('product_id'=>5, 'category_id'=>2)
); 

Использовать функцию: -

$itme_list = array_sort($item_array, 'category_id', SORT_ASC);
print_r($itme_list);

Вывод:

Array
(
    [itemA] => Array
        (
            [product_id] => 1
            [category_id] => 1
        )

    [itemC] => Array
        (
            [product_id] => 3
            [category_id] => 1
        )

    [itemD] => Array
        (
            [product_id] => 4
            [category_id] => 1
        )

    [itemB] => Array
        (
            [product_id] => 2
            [category_id] => 2
        )

    [itemE] => Array
        (
            [product_id] => 5
            [category_id] => 2
        )

)

Примечание: Ссылочная ссылка: - Сортировать многомерный массив PHP на основе ключа?

Как отсортировать многомерный массивпо клавишам умножения?

...