PHP数组按元素排序

时间:2015-05-09 01:27:16

标签: php arrays sorting

我有一个拥有以下公司记录的php数组。 一旦创建 - 我想安排数组值或创建一个新的数组,所有公司按距离排列(从最小到最大)。关于如何完成这项工作的任何建议?

感谢。

<?php
$company_values = array(
    array(
        'entitysymbol' => 'ANF',
        'distance'     => '0.42',
    ),

    array(
        'entitysymbol' => 'MSFT',
        'distance'     => '0.50',
    ),

    array(
        'entitysymbol' => 'GOOG',
        'distance'     => '0.78',
    ),
);

3 个答案:

答案 0 :(得分:2)

尝试一下:

function cmp($a, $b) {
    if ($a['distance'] == $b['distance']) {
        return 0;
    }
    return ($a['distance'] < $b['distance']) ? -1 : 1;
}

usort($company_values,"cmp");

var_dump($company_values);

有关更多信息,请阅读usort函数。希望我有所帮助:)

答案 1 :(得分:1)

这是一些可以满足您需求的代码:

<?php
// Define your array that needs sorting
$company_values = array(
    array(
        'entitysymbol' => 'MSFT',
        'distance'     => '0.60',
    ),
    array(
        'entitysymbol' => 'ANF',
        'distance'     => '0.42',
    ),

    array(
        'entitysymbol' => 'GOOG',
        'distance'     => '0.57',
    ),
    array(
        'entitysymbol' => 'MSFT',
        'distance'     => '0.50',
    ),
    array(
        'entitysymbol' => 'ANF',
        'distance'     => '0.30',
    ),

    array(
        'entitysymbol' => 'GOOG',
        'distance'     => '0.78',
    ),
    array(
        'entitysymbol' => 'MSFT',
        'distance'     => '0.50',
    ),
    array(
        'entitysymbol' => 'ANF',
        'distance'     => '0.42',
    ),

    array(
        'entitysymbol' => 'GOOG',
        'distance'     => '0.88',
    )
);

// Function to initialise a, b, and c before we start our search
function refresh_dichotomy($array) {
    $a = 0;
    $b = sizeof($array) - 1;
    $c = (int)(($a + $b) / 2);
    return [$a, $b, $c];
}

// Recursive dichotomy function to close in on where we need to insert the next element
function get_next_indexes($a, $b, $c, $array, $key, $value) {
    // If the value stored in the middle element is higher
    if($array[$c][$key] > $value) {
        // We lower the value of b
        $b = $c;
    // Otherwise
    } else {
        // We increse the value of a
        $a = $c;
    }
    // If a and b are not adjacent
    if($b - $a > 1) {
        // Get the middle value
        $c = (int)(($a + $b) / 2);
        // And dig deeper
        $a = get_next_indexes($a, $b, $c, $array, $key, $value);
    }
    return $a;
}

// Function to Fill the new array with the sorted values of the old one
function sort_array($old_array) {
    // Add the first element
    $new_array = Array($old_array[0]);
    // Cycle through the remaining elements
    for($i = 1; $i < sizeof($old_array); $i++) {
        // First check if the next element is smaller than the smallest value
        if($old_array[$i]['distance'] < $new_array[0]['distance']) {
            // If it is, then put it in first place
            array_splice($new_array, 0, 0, Array($old_array[$i]));
        }
        // Or if the next element is bigger than the biggest value
        else if($old_array[$i]['distance'] > $new_array[count($new_array) - 1]['distance']) {
            // If it is, then put it in last place
            array_splice($new_array, count($new_array), 0, Array($old_array[$i]));
        // Otherwise, find where we need to insert the next element
        } else {
            // Create 3 variables that will help us search via dichotomy
            $a;
            $b;
            $c;
            // Initialise their values to fit the current size of the new array
            $init = refresh_dichotomy($new_array);
            $a = $init[0];
            $b = $init[1];
            $c = $init[2];
            // Find where we need to insert our next value
            $a = get_next_indexes($a, $b, $c, $new_array, 'distance', $old_array[$i]['distance']);

            // Insert our new element
            array_splice($new_array, $a+1, 0, Array($old_array[$i]));
        }
    }
    return $new_array;
}

// Create an array to store the sorted values
$sorted_company_values = array();

// Sort !
$sorted_company_values = sort_array($company_values);

// Preview before and after
print_r($company_values);
echo("<br><br>");
print_r($sorted_company_values);

?>

此代码创建一个包含排序后的值的新数组,如果您不需要新数组,请替换:

$sorted_company_values = sort_array($company_values);

作者

$company_values = sort_array($company_values);

基本上,这是通过recursive insertion sortdichotomy来实现(more here) binary search

答案 2 :(得分:1)

正确答案:

usort($array, function ($a, $b)
{
    if (abs($a['distance'] - $b['distance']) <= 0.0001)
    {
        return 0; # equal
    }

    return $a['distance'] <=> $b['distance']; # swap $a and $b here for DESC order
});

我想强调一点,当您处理浮点值时,不应像整数那样比较它们。主要是因为浮点数可以表示任何数字,例如0.1可以同时存储为0.09999999970.1000000003。为避免此问题,您应该引入“ epsilon”变量(此处等于0.0001),这样您就可以说“两个浮点数之间的差小于epsilon,因此我们应将它们的值设为相等的数字”。

更多信息可在此处找到:Floating point numbers,请参阅带有“浮点精度”标题的警告。