我有以下数组:
array(174) { [0]=> string(5) "3.0.3" [1]=> string(5) "3.0.2" [2]=> string(5) "3.0.1" [3]=> string(5) "3.0.0" [9]=> string(5) "2.9.5" [10]=> string(5) "2.9.4" [11]=> string(5) "2.9.3" [12]=> string(5) "2.9.2" [13]=> string(5) "2.9.1" [14]=> string(5) "2.9.0" [18]=> string(6) "2.8.11" [19]=> string(6) "2.8.10" [20]=> string(5) "2.8.9" }
我需要找到唯一一对前两个数字x.x的最高第3个数字。在这个例子中,预期结果必须是3.0.3,2.9.5,2.8.11。
答案 0 :(得分:2)
首先,您必须按主要版本对版本进行分组。之后,您只需要使用version_compare
函数按降序对结果组进行排序,并返回每个组的第一个元素:
$versions = array("3.0.3", "3.0.2", "3.0.1", "3.0.0", "2.9.5", "2.9.4",
"2.9.3", "2.9.2", "2.9.1", "2.9.0", "2.8.11", "2.8.10", "2.8.9"
);
$groupedVersions = array();
foreach ($versions as $version) {
preg_match('/^\d+\.\d+/', $version, $majorVersion);
if (!isset($groupedVersions[$majorVersion[0]])) {
$groupedVersions[$majorVersion[0]] = array($version);
} else {
$groupedVersions[$majorVersion[0]][] = $version;
}
}
$groupedVersions = array_map(function ($versions) {
usort($versions, 'version_compare');
return array_reverse($versions);
}, $groupedVersions);
$latestVersions = array_reduce($groupedVersions, function ($carry, $versions) {
$carry[] = $versions[0];
return $carry;
}, array());
echo '<pre>';
var_dump($latestVersions);
echo '</pre>';
结果将是:
array(3) {
[0]=>
string(5) "3.0.3"
[1]=>
string(5) "2.9.5"
[2]=>
string(6) "2.8.11"
}
答案 1 :(得分:2)
在PHP中对数组数据进行分组时,根据分组条件生成临时键通常是最有效的。
我将根据来自What every digit means in software version (1.7.1.0, for example)?
的可接受答案使用一些版本术语在这种情况下,将使用前两个整数(主要和次要版本)(并且必须使用定界字符将其保持分隔,以避免数据冲突)。进行迭代时,检查输出集合中是否存在临时键。如果没有,请添加它。如果是这样,请检查第三个整数(维护版本)是否大于该主要次要版本组的存储维护版本-如果是,则替换存储的主要次要版本组的值。
这在下面的代码段中非常简洁。如果您需要为输出建立索引,请调用 public bool IsApproved
{
get { return _IsApproved; }
set { _IsApproved = value; OnPropertyChanged("IsApproved"); }
}
,否则省略该步骤。
代码:(Demo)
array_values()
输出:
$versions = [
"3.0.1", "3.0.3", "3.0.2", "3.0.0",
"2.9.4", "2.9.3", "2.9.2", "2.9.5", "2.9.1", "2.9.0",
"2.8.1", "2.8.11", "2.8.10"
];
foreach ($versions as $version) {
$ints = explode('.', $version, 3);
$tempKey = "{$ints[0]}.{$ints[1]}";
if (!isset($result[$tempKey]) || version_compare($version, $result[$tempKey], 'gt')) {
$result[$tempKey] = $version;
}
}
var_export(array_values($result));
使用array (
0 => '3.0.3',
1 => '2.9.5',
2 => '2.8.11',
)
是比较版本的合适工具,但是如果希望对维护版本值进行简单的整数到整数比较,可以避免使用。这将花费更多的内存,因为您还需要存储一组分组的维护版本整数以进行比较。我建议只比较完整版本的字符串。
答案 2 :(得分:1)
您只能使用explode()
并比较每个主要代号的最后一个值,然后构建具有主要和次要版本的关联数组:
<?php
$arr = array(0 => "3.0.3", 1 => "3.0.2", 2 => "3.0.1", 3 => "3.0.0", 9 => "2.9.5", 10 => "2.9.4", 11 => "2.9.3", 12 => "2.9.2", 13 => "2.9.1", 14 => "2.9.0", 18 => "2.8.11", 19 => "2.8.10", 20 => "2.8.9");
$versions = array();
$final = array();
foreach ($arr as $version) {
$explode = explode('.', $version); // split all parts
$end = '';
$begin = '';
if (count($explode) > 0) {
$end = array_pop($explode); // removes the last element, and returns it
if (count($explode) > 0) {
$begin = implode('.', $explode); // glue the remaining pieces back together
}
}
if(!empty($versions[$begin])){
if($versions[$begin] < $end){
$versions[$begin] = $end;
}
}else{
$versions[$begin] = $end;
}
}
foreach($versions as $key=>$value){
$final[] = "$key.$value";
}
print_r($final);
?>
输出:
Array
(
[0] => 3.0.3
[1] => 2.9.5
[2] => 2.8.11
)