Group Array Elements by Letter Range

后端 未结 3 1805
忘了有多久
忘了有多久 2021-01-22 17:20

I have a simple array with some names in it and I want to group them by their first letter. E.g. all names with A to C as first letter go in an array and D to F go to another on

3条回答
  •  时光取名叫无心
    2021-01-22 17:40

    This is a good use of array_reduce in a non-scalar fashion:

    function keyize(string $word, $stride = 3): string {
        $first = strtoupper($word{0});
        $index = (int)floor((ord($first) - ord('A'))/$stride);
        return implode('', array_chunk(range('A', 'Z'), $stride)[$index]);
    }
    
    function bucketize(array $words, $stride = 3): array {
        return array_reduce(
            $words,
            function ($index, $word) use ($stride) {
                $index[keyize($word, $stride)][] = $word;
                return $index;
            },
            []
        );
    }
    
    $words = [ 'alpha', 'Apple', 'Bravo', 'banana', 'charlie', 'Cucumber', 'echo', 'Egg', ];
    shuffle($words);
    $buckets = bucketize($words, 3); // change the number of characters you want grouped, eg 1, 13, 26
    ksort($buckets);
    var_dump($buckets);
    

    So we're using array_reduce to walk - and simultaneously build - the buckets. It's not the most efficient as implemented, because the bucket array is copied through each closure invocation. However, it's compact.

提交回复
热议问题