我有一个结果列表(请参阅下面的 JSON ),我需要选择前10名。这里他们在json中,但我将json_decoding成数组比如$ coureValues [" BUS1067"] == 117.1
我使用arsort($ courseValues)按顺序获取它们,如下面的 JSON 。
我需要选择前10名,但我需要强制执行至少4" BUS",至少2" CMP"以及至少1 SAF的约束。因此,例如,如果前10名中没有SAFxxxx,但有6个BUS和2个CMP,我想删除最低得分总线并添加得分最高的SAF。最后,考虑到约束条件,我想要的只是一个前10名的php数组。
JSON
{
"BUS1067": 117.1,
"BUS1057": 86.06,
"BUS1073": 79,
"BUS1068": 74.08,
"BUS1077": 74,
"BUS1001": 71,
"BUS1066": 68,
"BUS1076": 67.05,
"BUS1011": 64,
"BUS1054": 64,
"BUS1006": 63,
"CMP1091": 62,
"BUS1000": 60,
"CMP1083": 59,
"SAF1007": 58,
"CMP1073": 56,
"CMP1044": 55,
"CMP1029": 55,
"CMP1082": 53,
"CMP1089": 50,
"CMP1042": 48,
"CMP1070": 46,
"CMP1074": 45,
"BUS1074": 31,
"BUS1009": 20,
"BUS1003": 10,
"BUS1058": 1.09,
"BUS1061": 1.07,
"BUS1056": 1.04,
"CMP1081": 1.03,
"SAF1021": 1.01,
"CMP1064": 0,
"CMP1039": 0,
"CMP1047": 0,
"SAF1045": 0,
"SAF1047": 0,
"CMP1063": 0,
"SAF1020": 0,
"SAF1043": 0,
"SAF1032": 0,
"SAF1038": 0,
"BUS1075": 0,
"SAF1002": 0,
"CMP1037": 0,
"BUS1040": 0,
"CMP1078": 0,
"BUS1013": 0,
"CMP1080": 0,
"BUS1002": 0,
"BUS1048": 0,
"BUS1071": 0,
"CMP1072": 0,
"CMP1088": 0,
"CMP1084": 0,
"BUS1031": 0,
"BUS1055": 0,
"BUS1063": 0,
"BUS1072": 0,
"SAF1013": 0,
"BUS1012": 0,
"SAF1006": 0,
"CMP1049": -20,
"CMP1048": -20,
"CMP1050": -20,
"CMP1075": -20,
"CMP1038": -925,
"CMP1041": -929,
"CMP1079": -933.98
}
我正在寻找的是一种简单,优雅的方式。我可以“完成它”#34;但是想到的代码是混乱而且不清楚的,似乎有一些通用的算法"或者我应该使用的排序功能。
更新:代码: 根据要求,这是我做一个简单的事情的糟糕代码
<?php
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$minRequired=array("BUS"=>4, "CMP"=>2, "SAF"=>1);
$pathLength=10;
$selected=array();
//get top results to satisfy minimum required
foreach ($minRequired as $courseType => $min) {
foreach($courseValues as $key => $val){
if(substr($key, 0, 3) == $courseType && $min)
{
$selected[$key]=$val;
$min--;
if($min==0)
break;
}
}
}
//fill in the remaining with the top results
foreach($courseValues as $k=>$v){
if(count($selected)<$pathLength)
{
if(!array_key_exists($k, $selected))
$selected[$k]=$v;
}
else
break;
}
arsort($selected);
foreach($selected as $k=>$v)
echo "$k: $v<br>";
?>
答案 0 :(得分:0)
$ topten = array_keys(array_slice(arsort($ courseValues),0,10)); ?
好的,抱歉没有彻底阅读这个问题:)
答案 1 :(得分:0)
我首先要创建一个php数组,其中前缀为键,所需的数字如下所示:
$prefixes = array("BUS" => 4, "CMP" => 2, "SAF" => 1);
然后,由于您需要10个元素并且值的总和为7,因此您可以从任何类别中选择3个元素。那么循环应该是这样的:
基本理念:
虽然您没有排序列表中的10个元素:
获取元素。
提取前缀。
如果(前缀数组中存在前缀,且相应的值大于0), 或(剩余前缀值的总和小于所需元素的数量),然后将其添加到结果中。
代码:
$results = array();
foreach ($courseValues as $course => $courseValue) {
$prefix = substr($course, 0, 3);
if (isset($prefixes[$prefix]) && $prefixes[$prefix--] >= 0) {
$results[$course] = $courseValue;
}
else if (array_sum($prefixes) < 10 - count($results)) {
$results[$course] = $courseValue;
}
if (count($results) == 10) {
break;
}
}
注意:这是假设$ courseValues按$ courseValue
排序答案 2 :(得分:0)
我的解决方案:
好的,我已经把它归结为一个foreach循环。这是完整的解决方案:
$jsonWeights='{ "BUS1067": 117.1, "BUS1057": 86.06, "BUS1073": 79, "BUS1068": 74.08, "BUS1077": 74, "BUS1001": 71, "BUS1066": 68, "BUS1076": 67.05, "BUS1011": 64, "BUS1054": 64, "BUS1006": 63, "CMP1091": 62, "BUS1000": 60, "CMP1083": 59, "SAF1007": 58, "CMP1073": 56, "CMP1044": 55, "CMP1029": 55, "CMP1082": 53, "CMP1089": 50, "CMP1042": 48, "CMP1070": 46, "CMP1074": 45, "BUS1074": 31, "BUS1009": 20, "BUS1003": 10, "BUS1058": 1.09, "BUS1061": 1.07, "BUS1056": 1.04, "CMP1081": 1.03, "SAF1021": 1.01, "CMP1064": 0, "CMP1039": 0, "CMP1047": 0, "SAF1045": 0, "SAF1047": 0, "CMP1063": 0, "SAF1020": 0, "SAF1043": 0, "SAF1032": 0, "SAF1038": 0, "BUS1075": 0, "SAF1002": 0, "CMP1037": 0, "BUS1040": 0, "CMP1078": 0, "BUS1013": 0, "CMP1080": 0, "BUS1002": 0, "BUS1048": 0, "BUS1071": 0, "CMP1072": 0, "CMP1088": 0, "CMP1084": 0, "BUS1031": 0, "BUS1055": 0, "BUS1063": 0, "BUS1072": 0, "SAF1013": 0, "BUS1012": 0, "SAF1006": 0, "CMP1049": -20, "CMP1048": -20, "CMP1050": -20, "CMP1075": -20, "CMP1038": -925, "CMP1041": -929, "CMP1079": -933.98 }';
$courseValues=json_decode($jsonWeights,true);
arsort($courseValues);
$required=array("BUS"=>4, "CMP"=>2, "SAF"=>1,"Total" => 10);
$selected=array();
foreach($required as $type => $min)
foreach($courseValues as $key => $val)
if(count($selected)<$required['Total']
&&($type=='Total'||(substr($key,0,3)==$type && $min-->0)))
$selected[$key]=$val;
如果有人有更好的想法,我会把它打开