github.com/richardwilkes/toolbox@v1.121.0/collection/slice/column_sort.go (about)

     1  // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, version 2.0. If a copy of the MPL was not distributed with
     5  // this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  //
     7  // This Source Code Form is "Incompatible With Secondary Licenses", as
     8  // defined by the Mozilla Public License, version 2.0.
     9  
    10  package slice
    11  
    12  import "slices"
    13  
    14  // ColumnSort sorts the slice in place using the provided comparison function. The resulting order will be as if the
    15  // slice was divided into columns and each column was sorted independently. If the slice is not evenly divisible by
    16  // the number of columns, the extra elements will be distributed across the columns from left to right.
    17  func ColumnSort[S ~[]E, E any](s S, columns int, cmp func(a, b E) int) {
    18  	slices.SortFunc[S, E](s, cmp)
    19  	if columns > 1 && len(s) > columns {
    20  		replacement := make([]E, len(s))
    21  		step := len(s) / columns
    22  		extra := len(s) - step*columns
    23  		i := 0
    24  		j := 0
    25  		k := 1
    26  		for i < len(s) {
    27  			for c := 0; c < columns; c++ {
    28  				replacement[i] = s[j]
    29  				i++
    30  				if i >= len(s) {
    31  					break
    32  				}
    33  				j += step
    34  				if extra > c {
    35  					j++
    36  				}
    37  				if j >= len(s) {
    38  					j = k
    39  					k++
    40  				}
    41  			}
    42  		}
    43  		copy(s, replacement)
    44  	}
    45  }