如何过滤每个次要版本中保留最高补丁程序版本的数组?

问题描述 投票:-3回答:3

我有以下数组:

阵列(174){[0] =>字符串(5)“ 3.0.3”[1] =>字符串(5)“ 3.0.2”[2] =>字符串(5)“ 3.0.1”[3] =>字符串(5)“ 3.0.0”[9] =>字符串(5)“ 2.9.5”[10] =>字符串(5)“ 2.9.4”[11] =>字符串(5)“ 2.9.3”[12] =>字符串(5)“ 2.9.2”[13] =>字符串(5)“ 2.9.1”[14] =>字符串(5)“ 2.9.0”[18] =>字符串(6)“ 2.8.11”[19] =>字符串(6)“ 2.8.10”[20] =>字符串(5)“ 2.8.9”}

我需要为前两个数字x.x的唯一对找到最高的第三个数字。对于此示例,预期结果必须为:

3.0.3,2.9.5,2.8.11

这是我尝试过的:

foreach ($array as $key => $value) {
    $test = substr($value, 0, 3);
    $a = strtr($value, array('.' => '', ',' => ''));
    $b = (int) $a;
    $c = substr($b, 0, 2);
    $new_array = array($c);
    $result = array_unique($new_array);
    print_object($result);
}
php arrays semantic-versioning
3个回答
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
投票
您只能使用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 )


0
投票
在PHP中对数组数据进行分组时,根据分组条件生成临时键通常是最有效的。

我将基于以下来源的答案使用一些版本术语:What every digit means in software version (1.7.1.0, for example)?

在这种情况下,使用前两个整数(主要和次要版本)(并且必须保持它们之间以定界符分隔,以避免数据冲突)。进行迭代时,检查输出集合中是否存在临时键。如果没有,请添加它。如果是这样,请检查第三个整数(维护版本)是否大于该主要次要版本组的存储维护版本-如果是,则替换存储的主要次要版本组的值。

这在下面的代码段中非常简洁。如果您需要对输出进行索引,请调用array_values(),否则忽略该步骤。

代码:(Demo

$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', )

使用version_compare()是比较版本的合适工具,但是如果您希望对维护版本值进行简单的整数到整数比较,可以避免使用。这将花费更多的内存,因为您还需要存储一组分组的维护版本整数以进行比较。我建议只比较完整版本的字符串。
© www.soinside.com 2019 - 2024. All rights reserved.