首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用定义必须超过的数值的关联数组筛选3级数组

使用定义必须超过的数值的关联数组筛选3级数组
EN

Stack Overflow用户
提问于 2017-01-09 18:32:42
回答 2查看 472关注 0票数 1

我有一个具有技能I及其合格分数/分数的关联数组。例如:

代码语言:javascript
复制
Array
(
    [3] => 2 // skill => eligible marks
    [63] => 6
    [128] => 3
)

我有一个多维数组,其中的第一级键是学生I。第二级包含索引子数组,将技能ids和分数/分数表示为2元素关联数组。

代码语言:javascript
复制
Array
(
    [22] => Array
        (
            [0] => Array
                (
                    [skill_id] => 3
                    [gd_score] => 4
                )

            [1] => Array
                (
                    [skill_id] => 128
                    [gd_score] => 6
                )

        )

    [23] => Array
        (
            [0] => Array
                (
                    [skill_id] => 128
                    [gd_score] => 3
                )

        )

    [24] => Array
        (
            [0] => Array
                (
                    [skill_id] => 3
                    [gd_score] => 7
                )

            [1] => Array
                (
                    [skill_id] => 63
                    [gd_score] => 8
                )

            [2] => Array
                (
                    [skill_id] => 128
                    [gd_score] => 9
                )

        )

)

我想根据第一个数组中的值过滤学生。

我想让所有的学生:

  • 技能3分数大于2和
  • 技能63分大于6分
  • 技能128分大于3分。

如果满足所有条件,则返回学生id。因为只有学生24满足所有要求,所以输出应该是[24] --一个具有单个元素的数组。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-09 20:11:31

使用以下方法:

代码语言:javascript
复制
$marks = array
(
    3 => 2, // skill => eligible marks
    63 => 6,
    128 => 3
);

// $arr is your initial array of student data
$student_ids = [];
$marks_count = count($marks);
foreach ($arr as $k => $items) {
    // if number of marks coincide
    if ($marks_count != count($items)) {
        continue;
    }
    
    foreach ($items as $item) {
        if (!isset($marks[$item['skill_id']]) 
            || $marks[$item['skill_id']] >= $item['gd_score']
        ) {
            continue 2;
        }
    }
    $student_ids[] = $k;
}

print_r($student_ids);

产出:

代码语言:javascript
复制
Array
(
    [0] => 24
)

测试链接:https://eval.in/private/10a7add53b1378

票数 2
EN

Stack Overflow用户

发布于 2022-01-17 05:57:02

@RomanPerekhrest提供了一种高效的嵌套循环方法,它带有条件早期的continue。我确实认为,在某些情况下,关于数据质量的假设会带来麻烦,但我将避免发明代码污染测试用例。

无论如何,我不认为我以前需要用array_udiff_assoc()做实验,所以这是一个很好的机会。

我的片段将联合过滤掉所有的第一级条目,当所需的测试缺失或实际分数不大于资格分数时。

我的代码片段并不是为了优于罗曼的嵌套循环而设计的,我也没有对其进行基准测试。我只想提供一个简洁的,功能式的方法。

样本数据:

代码语言:javascript
复制
$criteria = [3 => 2, 63 => 6, 128 => 3];

$allScores = [
    22 => [
        ['skill_id' => 3, 'gd_score' => 4],
        ['skill_id' => 999, 'gd_score' => 9],
        ['skill_id' => 128, 'gd_score' => 7],
    ],
    23 => [
        ['skill_id' => 128, 'gd_score' => 3],
    ],
    24 => [
        ['skill_id' => 63, 'gd_score' => 8],
        ['skill_id' => 3, 'gd_score' => 7],
        ['skill_id' => 128, 'gd_score' => 9],
    ],
    25 => [
        ['skill_id' => 3, 'gd_score' => 7],
        ['skill_id' => 63, 'gd_score' => 8],
        ['skill_id' => 128, 'gd_score' => 1],
    ],
    26 => [
        ['skill_id' => 3, 'gd_score' => 2],
        ['skill_id' => 63, 'gd_score' => 6],
        ['skill_id' => 128, 'gd_score' => 3],
    ],
];

代码:(演示)

代码语言:javascript
复制
var_export(
    array_keys(
        array_filter(
            $allScores,
            fn($scores) => !array_udiff_assoc(
                $criteria,
                array_column($scores, 'gd_score', 'skill_id'),
                fn($cVal, $sVal) => $cVal >= $sVal
            )
        )
    )
);

输出:

代码语言:javascript
复制
array (
  0 => 24,
)

如果我要制作一个嵌套的循环脚本,(假设技能分数不能为负值),我将构建它如下:(演示)

代码语言:javascript
复制
$result = [];
foreach ($allScores as $key => $scores) {
    $skillScores = array_column($scores, 'gd_score', 'skill_id');
    foreach ($criteria as $id => $toBeat) {
        if (($skillScores[$id] ?? 0) <= $toBeat) {
            continue 2;
        }
    }
    $result[] = $key;
}
var_export($result);

与之前的功能片段一样,这个片段提供了相同的输出,并允许在不破坏业务规则的情况下存在可选的技能数据。使用array_column()创建查找数组避免了循环遍历每个规则的分数子数组的需要。

第二个片段可能会比第一个片段更好,但是如果是这样的话,我不认为这两者之间的区别是显而易见的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41554606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档