sigs.k8s.io/kueue@v0.6.2/pkg/util/slices/slices.go (about)

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package slices
    18  
    19  // ToMap creates a map[K]V out of the provided slice s using mf() to get the key and value
    20  // for a given index i.
    21  //
    22  // The caller can compare the length of the map to the one of the slice in order to detect
    23  // potential key conflicts.
    24  func ToMap[K comparable, V any, S ~[]E, E any](s S, mf func(int) (K, V)) map[K]V {
    25  	if s == nil {
    26  		return nil
    27  	}
    28  
    29  	if len(s) == 0 {
    30  		return map[K]V{}
    31  	}
    32  
    33  	ret := make(map[K]V, len(s))
    34  	for i := range s {
    35  		k, v := mf(i)
    36  		ret[k] = v
    37  	}
    38  	return ret
    39  }
    40  
    41  // ToRefMap creates a map[K]*S out of the provided slice s []S using key() to create the map keys.
    42  //
    43  // The caller can compare the length of the map to the one of the slice in order to detect
    44  // potential key conflicts.
    45  func ToRefMap[K comparable, S ~[]E, E any](s S, key func(*E) K) map[K]*E {
    46  	return ToMap(s,
    47  		func(i int) (K, *E) {
    48  			return key(&s[i]), &s[i]
    49  		})
    50  }
    51  
    52  // Map creates a new slice with the same number elements as the input s with
    53  // the values generated by mapFunc
    54  func Map[From any, To any, S ~[]From](s S, mapFunc func(*From) To) []To {
    55  	if s == nil {
    56  		return nil
    57  	}
    58  	ret := make([]To, len(s))
    59  	for i := range s {
    60  		ret[i] = mapFunc(&s[i])
    61  	}
    62  	return ret
    63  }
    64  
    65  // CmpNoOrder returns true if the two provided slices have the same elements
    66  // regardless of their order.
    67  func CmpNoOrder[E comparable, S ~[]E](a, b S) bool {
    68  	if len(a) != len(b) {
    69  		return false
    70  	}
    71  
    72  	counters := make(map[E]int, len(a))
    73  	for i := range a {
    74  		counters[a[i]]++
    75  		counters[b[i]]--
    76  	}
    77  
    78  	for _, v := range counters {
    79  		if v != 0 {
    80  			return false
    81  		}
    82  	}
    83  	return true
    84  }
    85  
    86  // Pick creates a new slice containing only the elements for which keep return true.
    87  func Pick[E any, S ~[]E](s S, keep func(*E) bool) S {
    88  	var ret S
    89  	for i := range s {
    90  		if keep(&s[i]) {
    91  			ret = append(ret, s[i])
    92  		}
    93  	}
    94  	return ret
    95  }