我有一个具有技能I及其合格分数/分数的关联数组。例如:
Array
(
[3] => 2 // skill => eligible marks
[63] => 6
[128] => 3
)我有一个多维数组,其中的第一级键是学生I。第二级包含索引子数组,将技能ids和分数/分数表示为2元素关联数组。
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
)
)
)我想根据第一个数组中的值过滤学生。
我想让所有的学生:
如果满足所有条件,则返回学生id。因为只有学生24满足所有要求,所以输出应该是[24] --一个具有单个元素的数组。
发布于 2017-01-09 20:11:31
使用以下方法:
$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);产出:
Array
(
[0] => 24
)发布于 2022-01-17 05:57:02
@RomanPerekhrest提供了一种高效的嵌套循环方法,它带有条件早期的continue。我确实认为,在某些情况下,关于数据质量的假设会带来麻烦,但我将避免发明代码污染测试用例。
无论如何,我不认为我以前需要用array_udiff_assoc()做实验,所以这是一个很好的机会。
我的片段将联合过滤掉所有的第一级条目,当所需的测试缺失或实际分数不大于资格分数时。
我的代码片段并不是为了优于罗曼的嵌套循环而设计的,我也没有对其进行基准测试。我只想提供一个简洁的,功能式的方法。
样本数据:
$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],
],
];代码:(演示)
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
)
)
)
);输出:
array (
0 => 24,
)如果我要制作一个嵌套的循环脚本,(假设技能分数不能为负值),我将构建它如下:(演示)
$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()创建查找数组避免了循环遍历每个规则的分数子数组的需要。
第二个片段可能会比第一个片段更好,但是如果是这样的话,我不认为这两者之间的区别是显而易见的。
https://stackoverflow.com/questions/41554606
复制相似问题