Sort an Array by keys based on another Array?

后端 未结 15 827
甜味超标
甜味超标 2020-11-22 03:29

Is it possible in PHP to do something like this? How would you go about writing a function? Here is an example. The order is the most important thing.

$custo         


        
相关标签:
15条回答
  • 2020-11-22 03:45

    Take one array as your order:

    $order = array('north', 'east', 'south', 'west');
    

    You can sort another array based on values using array_intersect­Docs:

    /* sort by value: */
    $array = array('south', 'west', 'north');
    $sorted = array_intersect($order, $array);
    print_r($sorted);
    

    Or in your case, to sort by keys, use array_intersect_key­Docs:

    /* sort by key: */
    $array = array_flip($array);
    $sorted = array_intersect_key(array_flip($order), $array);
    print_r($sorted);
    

    Both functions will keep the order of the first parameter and will only return the values (or keys) from the second array.

    So for these two standard cases you don't need to write a function on your own to perform the sorting/re-arranging.

    0 讨论(0)
  • 2020-11-22 03:46

    This function return a sub and sorted array based in second parameter $keys

    function array_sub_sort(array $values, array $keys){
        $keys = array_flip($keys);
        return array_merge(array_intersect_key($keys, $values), array_intersect_key($values, $keys));
    }
    

    Example:

    $array_complete = [
        'a' => 1,
        'c' => 3,
        'd' => 4,
        'e' => 5,
        'b' => 2
    ];
    
    $array_sub_sorted = array_sub_sort($array_complete, ['a', 'b', 'c']);//return ['a' => 1, 'b' => 2, 'c' => 3];
    
    0 讨论(0)
  • 2020-11-22 03:50

    PHP has functions to help you with this:

    $arrayToBeSorted = array('west', 'east', 'south', 'north');
    $order = array('north', 'south', 'east', 'west');
    
    // sort array
    usort($arrayToBeSorted, function($a, $b) use ($order){
        // sort using the numeric index of the second array
        $valA = array_search($a, $order);
        $valB = array_search($b, $order);
    
        // move items that don't match to end
        if ($valA === false)
            return -1;
        if ($valB === false)
            return 0;
    
        if ($valA > $valB)
            return 1;
        if ($valA < $valB)
            return -1;
        return 0;
    });
    

    Usort does all the work for you and array_search provides the keys. array_search() returns false when it can't find a match so items that are not in the sort array naturally move to the bottom of the array.

    Note: uasort() will order the array without affecting the key => value relationships.

    0 讨论(0)
  • 2020-11-22 03:50
    • sort as requested
    • save for int-keys (because of array_replace)
    • don't return keys are not existing in inputArray
    • (optionally) filter keys no existing in given keyList

    Code:

     /**
     * sort keys like in key list
     * filter: remove keys are not listed in keyList
     * ['c'=>'red', 'd'=>'2016-12-29'] = sortAndFilterKeys(['d'=>'2016-12-29', 'c'=>'red', 'a'=>3 ]], ['c', 'd', 'z']){
     *
     * @param array $inputArray
     * @param string[]|int[] $keyList
     * @param bool $removeUnknownKeys
     * @return array
     */
    static public function sortAndFilterKeys($inputArray, $keyList, $removeUnknownKeys=true){
        $keysAsKeys = array_flip($keyList);
        $result = array_replace($keysAsKeys, $inputArray); // result = sorted keys + values from input + 
        $result = array_intersect_key($result, $inputArray); // remove keys are not existing in inputArray 
        if( $removeUnknownKeys ){
            $result = array_intersect_key($result, $keysAsKeys); // remove keys are not existing in keyList 
        }
        return $result;
    }
    
    0 讨论(0)
  • 2020-11-22 03:55

    First Suggestion

    function sortArrayByArray($array,$orderArray) {
        $ordered = array();
        foreach($orderArray as $key) {
            if(array_key_exists($key,$array)) {
                $ordered[$key] = $array[$key];
                unset($array[$key]);
            }
        }
        return $ordered + $array;
    }
    

    Second Suggestion

    $properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
    

    I wanted to point out that both of these suggestions are awesome. However, they are apples and oranges. The difference? One is non-associative friendly and the other is associative friendly. If you are using 2 fully associative arrays then the array merge/flip will actually merge and overwrite the other associative array. In my case that is not the results I was looking for. I used a settings.ini file to create my sort order array. The data array I was sorting did not need to written over by my associative sorting counterpart. Thus array merge would destroy my data array. Both are great methods, both need to be archived in any developers toolbox. Based on your needs you may find you actually need both concepts in your archives.

    0 讨论(0)
  • 2020-11-22 03:56

    Just use array_merge or array_replace. Array_merge works by starting with the array you give it (in the proper order) and overwriting/adding the keys with data from your actual array:

    $customer['address'] = '123 fake st';
    $customer['name'] = 'Tim';
    $customer['dob'] = '12/08/1986';
    $customer['dontSortMe'] = 'this value doesnt need to be sorted';
    
    $properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
    //Or:
    $properOrderedArray = array_replace(array_flip(array('name', 'dob', 'address')), $customer);
    
    //$properOrderedArray -> array('name' => 'Tim', 'address' => '123 fake st', 'dob' => '12/08/1986', 'dontSortMe' => 'this value doesnt need to be sorted')
    

    ps - I'm answering this 'stale' question, because I think all the loops given as previous answers are overkill.

    0 讨论(0)
提交回复
热议问题