src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

maps.go (3144B)


      1 // Copyright 2023 The Go Authors. 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 moremaps contains more functions for working with maps.
      6 package moremaps
      7 
      8 import (
      9 	"cmp"
     10 	"iter"
     11 	"maps"
     12 	"slices"
     13 )
     14 
     15 // Arbitrary returns an arbitrary (key, value) entry from the map and ok is true, if
     16 // the map is not empty. Otherwise, it returns zero values for K and V, and false.
     17 func Arbitrary[K comparable, V any](m map[K]V) (_ K, _ V, ok bool) {
     18 	for k, v := range m {
     19 		return k, v, true
     20 	}
     21 	return
     22 }
     23 
     24 // Group returns a new non-nil map containing the elements of s grouped by the
     25 // keys returned from the key func.
     26 func Group[K comparable, V any](s []V, key func(V) K) map[K][]V {
     27 	m := make(map[K][]V)
     28 	for _, v := range s {
     29 		k := key(v)
     30 		m[k] = append(m[k], v)
     31 	}
     32 	return m
     33 }
     34 
     35 // KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
     36 func KeySlice[M ~map[K]V, K comparable, V any](m M) []K {
     37 	r := make([]K, 0, len(m))
     38 	for k := range m {
     39 		r = append(r, k)
     40 	}
     41 	return r
     42 }
     43 
     44 // ValueSlice returns the values of the map M, like slices.Collect(maps.Values(m)).
     45 func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V {
     46 	r := make([]V, 0, len(m))
     47 	for _, v := range m {
     48 		r = append(r, v)
     49 	}
     50 	return r
     51 }
     52 
     53 // SameKeys reports whether x and y have equal sets of keys.
     54 func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool {
     55 	ignoreValues := func(V1, V2) bool { return true }
     56 	return maps.EqualFunc(x, y, ignoreValues)
     57 }
     58 
     59 // Sorted returns an iterator over the entries of m in key order.
     60 func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
     61 	// TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
     62 	return func(yield func(K, V) bool) {
     63 		keys := KeySlice(m)
     64 		slices.Sort(keys)
     65 		for _, k := range keys {
     66 			if !yield(k, m[k]) {
     67 				break
     68 			}
     69 		}
     70 	}
     71 }
     72 
     73 // SortedFunc returns an iterator over the entries of m in the key order determined by cmp.
     74 func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] {
     75 	// TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted.
     76 	return func(yield func(K, V) bool) {
     77 		keys := KeySlice(m)
     78 		slices.SortFunc(keys, cmp)
     79 		for _, k := range keys {
     80 			if !yield(k, m[k]) {
     81 				break
     82 			}
     83 		}
     84 	}
     85 }
     86 
     87 // Delete is like delete(m, k) but reports whether deletion occurred.
     88 func Delete[M ~map[K]V, K comparable, V any](m M, k K) bool {
     89 	pre := len(m)
     90 	delete(m, k)
     91 	return pre != len(m)
     92 }
     93 
     94 // Entry is a key-value pair obtained from a map.
     95 type Entry[K comparable, V any] struct {
     96 	Key   K
     97 	Value V
     98 }
     99 
    100 // Entries returns a new unordered array of the entries of a map.
    101 func Entries[M ~map[K]V, K comparable, V any](m M) []Entry[K, V] {
    102 	entries := make([]Entry[K, V], 0, len(m))
    103 	for k, v := range m {
    104 		entries = append(entries, Entry[K, V]{k, v})
    105 	}
    106 	return entries
    107 }
    108 
    109 // FromEntries returns a new map into which the entries have been inserted in order.
    110 func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V {
    111 	m := make(map[K]V, len(entries))
    112 	for _, e := range entries {
    113 		m[e.Key] = e.Value
    114 	}
    115 	return m
    116 }