2015-04-06 37 views
0

寻找一种可能的方法来排序这个下面的数组。考虑字节。PHP:排序字节数组

Array 
(
    [0] => 100 MB 
    [4] => 10 MB 
    [8] => 1GB 
    [12] => 20 MB 
    [16] => 250 MB 
    [20] => 2GB 
    [24] => 4 MB 
    [28] => 500 MB 
    [32] => 50 MB 
    [36] => 5GB 
    [40] => 8GB 
    [44] => 0 MB 
) 
+0

基于“MB”值将字符串部分转换为数字(如'1 MB' ='1','1 GB' ='1000'),因为它是最小的类型,因此使用数组排序函数,然后再转回来?这就是我在这么晚的时候能想到的唯一的事情...... – Rasclatt 2015-04-06 08:09:51

回答

3

您可以使用自定义比较函数通过将字符串转换为字节值来排序此数组。

$arr = array(
    0 => "100 MB", 
    4 => "10 MB", 
    8 => "1GB", 
    12 => "20 MB", 
    16 => "250 MB", 
    20 => "2GB", 
    24 => "4 MB", 
    28 => "500 MB", 
    32 => "50 MB", 
    36 => "5GB", 
    40 => "8GB", 
    44 => "0 MB" 
); 

function toByte($value) { 
    $multiple = (stripos($value, "K") > 0) ? 1024 : 1; 
    $multiple *= (stripos($value, "M") > 0) ? 1048576 : 1; 
    $multiple *= (stripos($value, "G") > 0) ? 1073741824 : 1; 

    return floatval($value) * $multiple; 
} 

usort($arr, function($v1, $v2) { 
    return toByte($v1) - toByte($v2); 
}); 

var_dump($arr); 
0

你可以尝试natsort

https://php.net/manual/en/function.natsort.php

<?php 
    $array = array('10t', '2t', '3t'); 
    natsort($array); 

    echo '<pre>'; 
    print_r($array); 
    echo '</pre>'; 
?> 

//输出 阵列( 2T, 3T, 10吨 )

+0

这不起作用!输出是'阵列 ( [44] => 0 MB [8] => 1GB [20] => 2GB [24] => 4 MB [36] => 5GB [40] => 8GB [4] => 10 MB [12] => 20 MB [32] => 50 MB [0] => 100 MB [16] => 250 MB [28] => 500 MB )' – 2015-04-06 08:22:03

0

这种或那种方式,你需要将这些值转换成以t表示的数字他是相同的度量单位,以便您可以对它们进行比较。我可以想到两种方法:

  1. 遍历数组并将所有值转换为此度量单位,然后对新数组进行排序。
  2. 使用自定义比较函数对原始数组进行排序,在比较它们之前转换这些值。

第一种方法会更有效率,因为您只需在数组中执行一次转换操作,而在第二种方法中,您每次比较数字时都会执行这些转换,这几乎肯定会更多昂贵。如果可以复制或修改数组,则应该使用第一种方法。

在任何情况下,将这些值转换成一个简单的号码的功能将类似于以下内容:

$unitMultipliers = array(
    'b' => 1, 
    'kb' => 1024, 
    'mb' => 1048576, 
    'gb' => 1073741824, 
); 

function toBytes($stringValue) { 
    if (!preg_match('^/([0-9]+)\s*([a-z]+)$/i', $matches)) { 
     // If for some reason we can't find the pattern, exit early 
     return 0; 
    } 

    $bytes = (int) $matches[1]; 
    $unit = strtolower($matches[2]); 

    return $bytes * $unitMultipliers[$unit]; 
} 

实现的解决方案1和转换阵列,使用:

$newArray = array_map('toBytes', $originalArray); 
$sortedArray = sort($newArray); 

要实施解决方案2并使用自定义比较,请使用:

function compare($a, $b) { 
    $aBytes = toBytes($a); 
    $bBytes = toBytes($b); 

    if ($aBytes === $bBytes) { 
     return 0; 
    } 
    return $aBytes > $bBytes ? 1 : -1; 
} 

$sortedArray = usort($originalArray, 'compare'); 
0

试试这个:

$inpArr = array(0 => '100 MB', 4=>'10 MB', 8=>'1GB', 12=>'20 MB', 16=>'250 MB', 20=>'2GB', 24=>'4 MB', 28=>'500 MB', 32=>'50 MB', 36=>'5GB', 40=>'8GB', 44=>'0 MB'); 
$tempArr = array(); 
$sortArr = array(); 
foreach ($inpArr AS $key => $elem) { 
    $unit = trim(substr($elem, -2)); 
    if ($unit == 'GB') { 
     $tempArr[$key] = intval(trim(strstr($elem, 'GB', true))) * 1024; 
    } else { 
     $tempArr[$key] = intval(trim(strstr($elem, 'MB', true))); 
    } 
    asort($tempArr); 
} 
foreach ($tempArr AS $key => $elem) { 
    $sortArr[] = $inpArr[$key]; 
}