(PHP)特定的数组排序

时间:2011-09-30 03:01:47

标签: php arrays sorting

我希望有人能帮我解决一个小问题。在清醒过后,我仍然坚持,无法找到解决方案。我想这显然很简单。

我坚持使用数组结构并需要对它们进行排序。这是一个小数组的例子:

$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';

$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';

可能有n量的BRAND_N和n量的SUB_BRAND_N。

我的订单ID符合灵活的订单:

0 = out as in (dont worry about this, catch it at an earlier stage)
1 = BRAND_1.SUB_BRAND_1
2 = BRAND_1.SUB_BRAND_2
3 = BRAND_2.SUB_BRAND_1

如果这四种情况更多并且订单本身可能会发生变化,则会扩展。所以我必须使用ID。

订单应该更改数组中的位置,并将Id的值推到数组的顶部,例如:

订单ID = 2:

$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';

$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';

订单ID = 3:

$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';

$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';

到目前为止我已尝试过这个:

<?php

$order[1] = 'BRAND_1::SUB_BRAND_1';
$order[2] = 'BRAND_1::SUB_BRAND_2';
$order[3] = 'BRAND_2::SUB_BRAND_1';

// for testing
$orderId = 2;

// get the brand and sub_brand
$part = explode("::", $order[$orderId]); 

// set the new brand list
$newBrand[$part[0]]['name'] = $brand[$part[0]]['name'];
$newBrand[$part[0]]['list'][$part[1]] = $brand[$part[0]]['list'][$part[1]];

// unset the brand which should be first of the main brand array
unset($brand[$part[0]]['list'][$part[1]]);

// if there was only one list unset the whole brand part
if( count($brand[$part[0]]['list']) < 1 ) {
    unset( $brand[$part[0]] );
}

现在我有两个数组:

$品牌包括整个品牌,除了这个应该是第一个

$ newBrand仅包括应该位于顶部的品牌

现在我只需要将$ brand添加到$ newBrand但是有我的问题:) 尝试了很多不同的方法,从重建阵列到推送内容,替换或合并......但我总是在圈子里跑。

任何其他想法,更短的代码,更好的方法..?

我将整个代码写入codepad.org以获得更好的测试: Codepad example

任何帮助或建议都表示赞赏。

干杯!

编辑:

抱歉误解:

订单是代码之外的规范。目的是根据$ brand数组中顶部的orderId设置一个元素。 $ orderId将通过POST,GET或类调用传递。

$ order数组只是一个数组,它可以帮助我在代码中访问规范。

因此$ orderId匹配$ order数组的一个元素,并将返回此元素,该元素应位于$ brand数组的顶部。由于没有数字键,我决定使用“brand :: sub_brand”语法在两个深度级别进行访问。

希望这能更好地解释它。

由于

1 个答案:

答案 0 :(得分:1)

以下是一种可能的解决方案(测试here):

<?php

function getOrderingRules()
{
    return array(
        1 => 'BRAND_1.SUB_BRAND_1',
        2 => 'BRAND_1.SUB_BRAND_2',
        3 => 'BRAND_2.SUB_BRAND_1',
    );
}

function getOrderedBrands($brands, $orderId)
{
    $rules = getOrderingRules();
    if (!isset($rules[$orderId])) {
        throw new RuntimeException("Rule for order id '$orderId' is not specified");
    }

    $result = array();

    // Push the first element
    list($key, $subkey) = explode('.', $rules[$orderId]);
    $result[$key] = array(
        'name' => $brands[$key]['name'],
        'list' => array(
            $subkey => $brands[$key]['list'][$subkey],
        ),
    );

    // Push remaining elements in the order they appear in $rules
    foreach ($rules as $oid => $rule) {
        // Skip order id of the first element
        if ($oid == $orderId) {
            continue;
        }
        list($key, $subkey) = explode('.', $rules[$oid]);
        if (!isset($result[$key])) {
            $result[$key] = array(
                'name' => $brands[$key]['name'],
                'list' => array(),
            );
        }
        $result[$key]['list'][$subkey] = $brands[$key]['list'][$subkey];
    }

    return $result;
}

// Loading all brands (could be external source, like database)
$brand["BRAND_1"]["name"] = 'Brand Name 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['name'] = 'Headline Subbrand 2';
$brand["BRAND_1"]["list"]['SUB_BRAND_2']['text'] = 'text for Subbrand 2';

$brand["BRAND_2"]["name"] = 'Brand Name 2';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['name'] = 'Headline Subbrand 1';
$brand["BRAND_2"]["list"]['SUB_BRAND_1']['text'] = 'text for Subbrand 1';

// Sort and output
print_r(getOrderedBrands($brand, 1));
print_r(getOrderedBrands($brand, 2));
print_r(getOrderedBrands($brand, 3));

您应该知道,使用此数组结构($brands),您将无法设置如下的排序规则:

1 = BRAND_1.SUB_BRAND_1
2 = BRAND_2.SUB_BRAND_1
3 = BRAND_1.SUB_BRAND_2

因为一旦遇到BRAND_1键入的元素,就必须遍历所有子品牌。如果你没有这样的规则,一切都很好。否则你必须存储这样结构化的排序数组(因为实际上你正在分类子品牌,而不是品牌):

$subBrands = array(
    array(
        'name' => 'Headline Subbrand 1',
        'text' => 'Text for it',
        'parent' => 'BRAND_1',
        'key' => 'SUB_BRAND_1',
    ),
    array(
        'name' => 'Headline Subbrand 2',
        'text' => 'Text for it',
        'parent' => 'BRAND_1',
        'key' => 'SUB_BRAND_2',
    ),
);
$parentBrands = array(
    'BRAND_1' => 'Brand Name 1',
    'BRAND_2' => 'Brand Name 2',
);

然后你可以对$subBrands进行排序并迭代它