过滤包含模块和软件版本值的行并保留具有最高版本的唯一模块
Filter rows containing modules and software version values and retain unique modules with highest version
我有一个这样的数组:
Array (
[vendor] => Array (
[0] => Array ( [name] => module-one [version] => 1.7.0 )
[1] => Array ( [name] => module-one [version] => 1.8.0 )
[2] => Array ( [name] => module-two [version] => 1.8.0 )
[3] => Array ( [name] => module-two [version] => 1.2.0 )
[4] => Array ( [name] => module-three [version] => 1.9.0 )
[5] => Array ( [name] => module-three [version] => 1.8.0 )
)
)
我想通过键 name 比较数组,如果匹配则获取可用的最高版本,如下所示:
Array (
[vendor] => Array (
[0] => Array ( [name] => module-one [version] => 1.8.0 )
[1] => Array ( [name] => module-two [version] => 1.8.0 )
[2] => Array ( [name] => module-three [version] => 1.9.0 )
)
)
尝试这样的事情
// assuming your array is called $rows
$latest_modules = [];
foreach ($rows as $row) {
$name = $row['name'];
$version = $row['version'];
if (empty($latest_modules[$name]) || ($latest_modules[$name] < $version)) {
$latest_modules[$name] = $version;
}
}
print_r($latest_modules);
-- 更新
@nice_dev 指出比较不适用于所有版本情况。
例如,1.12.1 与 1.2.1 将 return 1.2.1 作为更大的版本,这是不正确的。
// assuming your array is called $rows
$latest_modules = [];
foreach ($rows as $row) {
$name = $row['name'];
$version = $row['version'];
if (empty($latest_modules[$name])) {
$latest_modules[$name] = $version;
}
else {
$latest_modules[$name] = max_version($latest_modules[$name], $version);
}
}
print_r($latest_modules);
function max_version($a, $b) {
$a_parts = explode('.', $a);
$b_parts = explode('.', $b);
if (count($a_parts) !== count($b_parts)) {
throw new \Exception('Both versions must be in same format major.minor.bugfix');
}
foreach ($a_parts as $key => $a_val) {
$b_val = $b_parts[$key] ?? 0;
if ($a_val > $b_val) {
return $a;
}
elseif ($b_val > $a_val) {
return $b;
}
// $a_val and $b_val are equal, continue through look at check next value.
}
// both values are the same, doesn't matter which one we return
return $a;
}
PHP 有一个 native version comparison function 让这项工作变得非常简单。按 name
值分组,当您遇到与特定组匹配的任何后续行时 - 如果版本更高,则只保存新行。
我已经更改了您的示例输入以表明多位数版本值将得到正确处理。
代码:(Demo)
$vendor = [
[ "name" => "module-one", "version" => "1.7.0" ],
[ "name" => "module-one", "version" => "1.8.0" ],
[ "name" => "module-two", "version" => "1.8.0" ],
[ "name" => "module-two", "version" => "1.12.0" ],
[ "name" => "module-three", "version" => "1.9.0" ],
[ "name" => "module-three", "version" => "1.8.0" ],
];
$result = [];
foreach ($vendor as $row) {
if (
!isset($result[$row['name']])
|| version_compare($result[$row['name']]['version'], $row['version'], '<')
) {
$result[$row['name']] = $row;
}
}
var_export(array_values($result));
输出:
array (
0 =>
array (
'name' => 'module-one',
'version' => '1.8.0',
),
1 =>
array (
'name' => 'module-two',
'version' => '1.12.0',
),
2 =>
array (
'name' => 'module-three',
'version' => '1.9.0',
),
)
我有一个这样的数组:
Array (
[vendor] => Array (
[0] => Array ( [name] => module-one [version] => 1.7.0 )
[1] => Array ( [name] => module-one [version] => 1.8.0 )
[2] => Array ( [name] => module-two [version] => 1.8.0 )
[3] => Array ( [name] => module-two [version] => 1.2.0 )
[4] => Array ( [name] => module-three [version] => 1.9.0 )
[5] => Array ( [name] => module-three [version] => 1.8.0 )
)
)
我想通过键 name 比较数组,如果匹配则获取可用的最高版本,如下所示:
Array (
[vendor] => Array (
[0] => Array ( [name] => module-one [version] => 1.8.0 )
[1] => Array ( [name] => module-two [version] => 1.8.0 )
[2] => Array ( [name] => module-three [version] => 1.9.0 )
)
)
尝试这样的事情
// assuming your array is called $rows
$latest_modules = [];
foreach ($rows as $row) {
$name = $row['name'];
$version = $row['version'];
if (empty($latest_modules[$name]) || ($latest_modules[$name] < $version)) {
$latest_modules[$name] = $version;
}
}
print_r($latest_modules);
-- 更新
@nice_dev 指出比较不适用于所有版本情况。
例如,1.12.1 与 1.2.1 将 return 1.2.1 作为更大的版本,这是不正确的。
// assuming your array is called $rows
$latest_modules = [];
foreach ($rows as $row) {
$name = $row['name'];
$version = $row['version'];
if (empty($latest_modules[$name])) {
$latest_modules[$name] = $version;
}
else {
$latest_modules[$name] = max_version($latest_modules[$name], $version);
}
}
print_r($latest_modules);
function max_version($a, $b) {
$a_parts = explode('.', $a);
$b_parts = explode('.', $b);
if (count($a_parts) !== count($b_parts)) {
throw new \Exception('Both versions must be in same format major.minor.bugfix');
}
foreach ($a_parts as $key => $a_val) {
$b_val = $b_parts[$key] ?? 0;
if ($a_val > $b_val) {
return $a;
}
elseif ($b_val > $a_val) {
return $b;
}
// $a_val and $b_val are equal, continue through look at check next value.
}
// both values are the same, doesn't matter which one we return
return $a;
}
PHP 有一个 native version comparison function 让这项工作变得非常简单。按 name
值分组,当您遇到与特定组匹配的任何后续行时 - 如果版本更高,则只保存新行。
我已经更改了您的示例输入以表明多位数版本值将得到正确处理。
代码:(Demo)
$vendor = [
[ "name" => "module-one", "version" => "1.7.0" ],
[ "name" => "module-one", "version" => "1.8.0" ],
[ "name" => "module-two", "version" => "1.8.0" ],
[ "name" => "module-two", "version" => "1.12.0" ],
[ "name" => "module-three", "version" => "1.9.0" ],
[ "name" => "module-three", "version" => "1.8.0" ],
];
$result = [];
foreach ($vendor as $row) {
if (
!isset($result[$row['name']])
|| version_compare($result[$row['name']]['version'], $row['version'], '<')
) {
$result[$row['name']] = $row;
}
}
var_export(array_values($result));
输出:
array (
0 =>
array (
'name' => 'module-one',
'version' => '1.8.0',
),
1 =>
array (
'name' => 'module-two',
'version' => '1.12.0',
),
2 =>
array (
'name' => 'module-three',
'version' => '1.9.0',
),
)