【问题标题】:PHP object to array sorting by associative keyPHP对象到数组按关联键排序
【发布时间】:2019-02-28 11:34:47
【问题描述】:

早上好,我对此感到震惊,但是,php 有超过 10 种方法来对数组进行排序,但我找不到一种按所需键动态排序的方法。

我不能设置一些类似 uksorts 的东西,因为它会被动态填充。我在前面使用 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;
}

事实是我想重新排序对象 bu 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 排序函数来实现它,或者它必须是自定义的?

谢谢

【问题讨论】:

  • 什么代码会产生结果?
  • “我不能设置像一些 uksorts 这样的东西,因为它会被动态填充。” - 你的意思是什么?
  • @splash58 没有重现结果的代码。结果是默认的...
  • @04FS 我的意思是,如果您必须对要排序的每个键进行自定义排序,这很乏味,我希望它可能是一些 php 内置函数,例如 ksort(array, assocKey , 方向),这很容易。

标签: php smarty


【解决方案1】:

为什么不能使用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 demo

这通过首先比较 category_id 字段来工作。
如果这些相同,那么我们比较product_id。使用减法以便product_ids 中较小的被排序较大的之前。

如果category_ids 不相同,那么我们对category_ids 执行与上面对product_id 执行的操作相同的操作。


要将其实现到您的视图中,请关注documentation

$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 数组即可。

【讨论】:

  • 这将使我每次想按不同的键排序时创建一个新的 soert 函数。我知道并尝试了不同的 php doc 数组排序函数,我正在寻找更有用的东西。我想无论如何我都必须为它创建一个库,但如果有一些内置的东西可以提供比我在 php doc 上看到的简单的“按第一个键或 DIY 排序”更多的东西,那可能会很好......
  • @JoelBonetRodríguez 我不明白您的要求...如果您想要自定义排序,那么我可以相应地修改函数,以便您可以更改对哪些列进行排序...您的问题没有t 真的清楚表明您可能希望在不同时间按不同列排序。
  • @JoelBonetRodríguez 我已经更新了我的代码,请检查它是否更适合您的应用程序。
【解决方案2】:

你可以试试这个功能。

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
        )

)

注意:参考链接:- Sort PHP multi-dimensional array based on key?

How to sort multidimensional array by multiply keys?

【讨论】:

  • 仅代码和仅链接的答案不是 IMO 的答案。一个好的答案应该解释问题和解决方案,以便 OP 和未来的访问者可以学习
  • @treyBake:谢谢你的建议。我会处理好这个
  • 这正是我不想要的。我的意思是,如果 PHP 上有一个内置函数可以在不进行自定义比较的情况下实现这一点,因为它很容易实现,但是当你需要多次重复它时会很乏味。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2011-06-21
相关资源
最近更新 更多