-
Notifications
You must be signed in to change notification settings - Fork 0
/
arrange.go
55 lines (54 loc) · 1.39 KB
/
arrange.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package forge
// Arrange inserts/removes a element 'el' at index 'idx'.
//
// It will perform equality check with 'key(el)'.
// When key function is nil, it cannot compare elements.
// So 'elems' will be returned as untouched.
//
// If a key for 'el' already exists, it will override the value
// only if user set 'override' to true.
//
// idx < 0 means remove the element.
// idx >= len(elems) means append it to the last.
//
// ex) When elems is []string{"a", "b", "c"} with given arguments,
// results will be same as following.
//
// elems = []string{"b", "c"} where path = "a" and idx = -1
// elems = []string{"a", "b", "c"} where path = "a" and idx = 0
// elems = []string{"b", "a", "c"} where path = "a" and idx = 1
// elems = []string{"b", "c", "a"} where path = "a" and idx = 2
//
func Arrange[T any, K comparable](elems []T, el T, idx int, key func(a T) K, override bool) []T {
if key == nil {
return elems
}
findIdx := -1
for i, e := range elems {
if key(e) == key(el) {
findIdx = i
break
}
}
if findIdx >= 0 {
if !override {
el = elems[findIdx]
}
elems = append(elems[:findIdx], elems[findIdx+1:]...)
}
if idx < 0 {
// remove
return elems
}
if idx < len(elems) {
// insert el at idx
var t T
elems = append(elems, t)
copy(elems[idx+1:], elems[idx:])
elems[idx] = el
return elems
}
// append
elems = append(elems, el)
return elems
}