List 去重



List 去重是很常见,通常用于检测和移除重复数据,去重可以分为两种,同时也都有对应的方法。

  1. 根据 key 去重
  2. 根据 value 去重

选择哪种去重方式,取决于是否存在 “唯一键”。

也就是说,如果你能根据一组字段构造唯一键,那就可以用方法 1,否则需要用方法 2。

最好选择方法 1,因为随着数据增多,方法 2 可能会导致更多的 runtime。

根据 Key 去重

要实现的是基于 key 或一组字段检测然后移除重复的数据。

我们实现的方式是根据 struct 推导将 list 转换为 “map”,然后再将其转回 list。

unique-list-by-key.cue

#elem: {
	key: string
	val: _
}

elems: [...#elem] & [
	{key: "a", val: 1},
	{key: "b", val: 1},
	// { key: "a", val: 2 }, // uncomment this line to see error
	{key: "b", val: 1},
]

set: [string]: #elem
set: {
	for e in elems {
		"\(e.key)": e
	}
}

uniq: [ for s in set {s}]

cue eval unique-list-by-key.cue

#elem: {
	key: string
	val: _
}
elems: [{
	key: "a"
	val: 1
}, {
	key: "b"
	val: 1
}, {
	key: "b"
	val: 1
}]
set: {
	a: {
		key: "a"
		val: 1
	}
	b: {
		key: "b"
		val: 1
	}
}
uniq: [{
	key: "a"
	val: 1
}, {
	key: "b"
	val: 1
}]

根据 Value 去重

这里要实现的是基于所有的 Value 检测并移除重复数据。

我们使用了 list 包还有 list 推导。

unique-list-by-val.cue

import "list"

#elem: {
	key: string
	val: _
}

elems: [...#elem] & [
	{key: "a", val: 1},
	{key: "b", val: 1},
	{key: "a", val: 2},
	{key: "b", val: 1},
]

// we compare the current element and add it if it does not appear in the remainder of the list
// in doing so, we add the last unique occurance to the result
uniq: [ for i, x in elems if !list.Contains(list.Drop(elems, i+1), x) {x}]

cue eval unique-list-by-val.cue

#elem: {
	key: string
	val: _
}
elems: [{
	key: "a"
	val: 1
}, {
	key: "b"
	val: 1
}, {
	key: "a"
	val: 2
}, {
	key: "b"
	val: 1
}]
uniq: [{
	key: "a"
	val: 1
}, {
	key: "a"
	val: 2
}, {
	key: "b"
	val: 1
}]
我们绝不会将你的邮箱分享给任何人。
2022 Hofstadter, Inc