github.com/searKing/golang/go@v1.2.117/exp/slices/group.go (about)

     1  // Copyright 2023 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package slices
     6  
     7  // Group returns a map group by all elements in s that have the same values.
     8  //
     9  // If s is nil, Group returns nil (zero map).
    10  //
    11  // If s is empty, Group returns an empty map.
    12  //
    13  // Else, Group returns a map group by all elements in s that have the same values.
    14  // TODO: accept [S ~[]E, M ~map[E]N, E comparable, N constraints.Number] if go support template type deduction
    15  func Group[S ~[]E, M map[E]N, E comparable, N int](s S) M {
    16  	// If s is nil, Split returns nil (zero map).
    17  	if s == nil {
    18  		return nil
    19  	}
    20  
    21  	// Below: s != nil
    22  
    23  	// If s is empty, Split returns an empty map.
    24  	if len(s) == 0 {
    25  		var emptyM = M{}
    26  		return emptyM
    27  	}
    28  
    29  	// Below: len(s) > 0 && f != nil
    30  	var m = M{}
    31  	for _, e := range s {
    32  		m[e] = m[e] + 1
    33  	}
    34  	return m
    35  }
    36  
    37  // GroupFunc returns a map satisfying f(c) within
    38  // all c in the map group by all elements in s that have the same values.
    39  //
    40  // If s is nil, GroupFunc returns nil (zero map).
    41  //
    42  // If s and f are both empty or nil, GroupFunc returns an empty map.
    43  //
    44  // Else, GroupFunc returns a map satisfying f(c)
    45  // within all c in the map group by all elements in s that have the same values.
    46  // TODO: accept [S ~[]E, M ~map[K]S, E any, K comparable] if go support template type deduction
    47  func GroupFunc[S ~[]E, M map[K]S, E any, K comparable](s S, f func(E) K) M {
    48  	// If s is nil, Split returns nil (zero submaps).
    49  	if s == nil {
    50  		return nil
    51  	}
    52  
    53  	// Below: s != nil
    54  
    55  	// If both s and f are empty or nil, Split returns an empty map.
    56  	if len(s) == 0 && f == nil {
    57  		var emptyM = M{}
    58  		return emptyM
    59  	}
    60  
    61  	// Below: len(s) > 0 && f != nil
    62  	var m = M{}
    63  	for _, e := range s {
    64  		k := f(e)
    65  		m[k] = append(m[k], e)
    66  	}
    67  	return m
    68  }