当前位置: 首页 > 面试题库 >

排序多维数组:对列包含子字符串进行优先排序,然后按第二列排序

阳兴文
2023-03-14
问题内容

我目前正在创建一种排序方法,该方法由mysql查询的值组成。

这是数组的简要视图:

    Array
    (
        [0] => Array
            (
                ['id'] = 1;
                ['countries'] = 'EN,CH,SP';
            )
        [1] => Array
            (
                ['id'] = 2;
                ['countries'] = 'GE,SP,SV';
            )
    )

我已经成功地基于数字id值进行了正常的排序,但是我想按“国家/地区”字段的内容对数组进行排序(如果在这种情况下包含设置的字符串和国家/地区代码),然后通过id字段。

以下代码段是我的第一个想法,但我不知道如何将其合并到工作功能中:

in_array('EN', explode(",",$a['countries']) );

你会怎么做?

谢谢!

不幸的是,我真的一无所获。

这是我目前拥有的东西,它给我的只有错误: uasort() [function.uasort]: Invalid comparison function

function compare($a, $b) {
    global $usercountry;

        if ( in_array($usercountry, $a['countries']) && in_array($usercountry, $a['countries']) ) {
            $return = 0;
        }

        else if (in_array($usercountry, $a['countries'])) {
            $return = 1;
        }

        else {
            $return = -1;
        }

        return $return;


        }

        $array= usort($array, "compare");

有谁可以给​​我提示如何进行操作吗?


问题答案:

我个人将与结合使用自定义(匿名)函数usort()

编辑:重新-您的评论。希望这将使您走上正确的道路。此功能为同时具有EN或都不具有EN的元素赋予相同的优先级,或者当仅具有EN的元素具有调整后的优先级。

usort($array,function ($a, $b) {
    $ac = strpos($a['countries'],'EN');
    $bc = strpos($b['countries'],'EN');
    if (($ac !== false && $bc !== false) || ($ac == false && $bc == false)) {
        return 0;
    }
    elseif ($ac !== false) {
        return 1;
    }
    else {
        return -1;
    }
});

另一方面,如果两个函数都具有EN,则该函数具有相同的优先级;如果一个函数具有EN,则该函数具有较高的优先级;如果两个都不具有EN,则进行文本比较。

usort($array,function ($a, $b) {
    $ac = strpos($a['countries'],'EN');
    $bc = strpos($b['countries'],'EN');
    if ($ac !== false && $bc !== false)) {
        return 0;
    }
    elseif ($ac !== false) {
        return 1;
    }
    elseif ($bc !== false) {
        return -1;
    }
    else {
        if ($a['countries'] == $b['countries']) {
            return 0;
        }
        elseif($a['countries'] > $b['countries']) {
            return 1;
        }
        else {
            return -1;
        }
    }
});

再次,希望这将给您足够的指导,以自己前进。如果您有任何问题,请随时发表更多评论,我将尽力提供帮助。
如果您想将多个属性与重量进行比较,请注意:尝试使用时髦的开关块,例如

$ac = array_flip(explode(',',$a['countries']));
$bc = array_flip(explode(',',$b['countries']));
switch (true) {
    case array_key_exists('EN',$ac) && !array_key_exists('EN',$bc):
        return 1;
    case array_key_exists('DE',$ac) && !array_key_exists('EN',$bc) && !array_key_exists('EN',$bc):
        return 1;
    // and so on
}

实际上,我在考虑复杂排序的问题,我想出了以下解决方案供您考虑。它将允许您根据出现在国家/地区索引中的关键字定义数字排名。这是代码,包括一个示例:

示例数组

$array = array(
    array(
        'countries' => 'EN,DE,SP',
    ),
    array(
        'countries' => 'EN,CH,SP',
    ),
    array(
        'countries' => 'DE,SP,CH',
    ),
    array(
        'countries' => 'DE,SV,SP',
    ),
    array(
        'countries' => 'EN,SP,FR',
    ),
    array(
        'countries' => 'DE,FR,CH',
    ),
    array(
        'countries' => 'CH,EN,SP',
    ),

);

排序程序

$rankings = array(
    'EN' => 10,
    'SP' => 8,
    'FR' => 7,
    'DE' => 5,
    'CH' => 3,
    'SV' => 1,
);
usort($array, function (&$a, &$b) use ($rankings) {
    if (isset($a['_score'])) {
        $aScore = $a['_score'];
    }
    else {
        $aScore = 0;
        $aCountries = explode(',',$a['countries']);
        foreach ($aCountries as $country) {
            if (isset($rankings[$country])) {
                $aScore += $rankings[$country];
            }
        }
        $a['_score'] = $aScore;
    }

    if (isset($b['_score'])) {
        $bScore = $b['_score'];
    }
    else {
        $bScore = 0;
        $bCountries = explode(',',$b['countries']);
        foreach ($bCountries as $country) {
            if (isset($rankings[$country])) {
                $bScore += $rankings[$country];
            }
        }
        $b['_score'] = $bScore;
    }
    if ($aScore == $bScore) {
        return 0;
    }
    elseif ($aScore > $bScore) {
        return -1;
    }
    else {
        return 1;
    }
});

注意:此代码会将排序 最高的整体排序到array的顶部 。如果您想要反向行为,请更改此:

    elseif ($aScore > $bScore) {

    elseif ($aScore < $bScore) {

请注意,大于符号已更改为小于符号。进行此更改将导致 排名最低的条目排在数组的顶部 。希望所有这些都对您有所帮助!

注意!

此代码将对您的数组进行一些小的更改,因为它将_score元素添加到每个数组。希望这不是问题,因为通过存储该值,我确实能够使速度提高两倍以上(在我的基准测试中,.00038-.00041降至.00016-.00018)。如果不是,请删除if检索缓存值的块,并让else块的内容每次执行,当然存储分数值的部分除外。

顺便说一下,这是var_export()数组排序后的转储:

array (
  0 => array (
    'countries' => 'EN,SP,FR',
    '_score' => 25,
  ),
  1 => array (
    'countries' => 'EN,DE,SP',
    '_score' => 23,
  ),
  2 => array (
    'countries' => 'EN,CH,SP',
    '_score' => 21,
  ),
  3 => array (
    'countries' => 'CH,EN,SP',
    '_score' => 21,
  ),
  4 => array (
    'countries' => 'DE,SP,CH',
    '_score' => 16,
  ),
  5 => array (
    'countries' => 'DE,FR,CH',
    '_score' => 15,
  ),
  6 => array (
    'countries' => 'DE,SV,SP',
    '_score' => 14,
  ),
)

请享用!



 类似资料:
  • 问题内容: 我有一个包含多个数组的数组,我想根据这些数组中的某个字符串对数组进行排序。 如何按名称排序,以便 阿尔伯特排 在首位, 齐默尔曼排 在最后? 我知道如果可以使用整数进行排序,但是字符串使我毫无头绪,该怎么办。 谢谢您帮忙!:) 问题答案: 这可以通过将支持函数作为参数传递给方法调用来实现。 像这样:

  • 问题内容: 我创建了一个sqlite数据库,该数据库具有一个存储温度值的表。第一次将温度值以升序写入数据库。然后,我将数据库中的温度值读取到一个列表中,然后将该列表添加到组合框中以选择温度- 效果很好。 结果列表为: 然后,我向数据库添加一个新的温度值,例如“ 33”。 它被附加到表的末尾。如果我现在阅读温度,列表将变为: 如果我做或,最终的结果是 有什么简单的方法可以按升序对列表进行排序,以便得

  • 我已经能够得到这个数组,因此它是使用' m '排序的,但是结果是按保护顺序排序的——因为所有包含' m '的字符串都在末尾。 我的打印输出显示:; 我考虑过使用indexOf(),但我还没能找到一种方法让它工作。 非常感谢您的建议!

  • 按列对数组进行排序,就像我想在这里对最后一行上的值进行排序一样,根据排序结果,同一行中其他列上的数字也可能会发生变化 例如

  • 问题内容: 有没有一种方法可以使用sort()方法或任何其他方法按列对列表进行排序?可以说我有清单: 我想对其进行排序,使其看起来像这样: 这样做的最佳方法是什么? 编辑: 现在,我遇到索引超出范围错误。我有一个二维数组,可以说1000行b 3列。我想根据第三列对其进行排序。这是正确的代码吗? 问题答案: 是。该内置接受的说法: 请注意,将返回一个新列表。如果要就地排序,请使用列表的方法(也可以方