根据字段子集的列表中的唯一元素
Unique elements from a list according to a subset of fields
给定一条像
这样的记录
data Foo = Foo { fooName :: Text, fooAge :: Int, fooCity :: Text }
有了这些元素的列表,在这个假设的 removeDupBy
函数的模型上,是否有一个函数可以仅删除字段子集上的重复项?
foos =
[
Foo "john" 32 "London",
Foo "joe" 18 "New York",
Foo "john" 22 "Paris",
Foo "john" 32 "Madrid",
Foo "joe" 17 "Los Angeles",
Foo "joe" 18 "Berlin"
]
> removeDupBy (\(Foo f) -> (fooName, fooAge)) foos
[
Foo "john" 32 "London",
Foo "joe" 18 "New York",
Foo "john" 22 "Paris",
Foo "joe" 17 "Los Angeles"
]
我可以实现我自己的,但更喜欢使用一个来自成熟库的库,它可能性能更高,并且对边缘情况更有弹性。我正在考虑使用 nub
,但我不确定如何将实际的 Foo
元素映射到 nub
会过滤掉的元组 (fooName, fooAge)
。
您可以使用 nubBy:
Prelude Data.List> nubBy (\x y -> (fooName x, fooAge x) == (fooName y, fooAge y)) foos
[Foo {fooName = "john", fooAge = 32, fooCity = "London"},
Foo {fooName = "joe", fooAge = 18, fooCity = "New York"},
Foo {fooName = "john", fooAge = 22, fooCity = "Paris"},
Foo {fooName = "joe", fooAge = 17, fooCity = "Los Angeles"}]
(输出格式化以增强可读性)
因为你只处理字符串和数字,你可以使用 Ord
实例来有效地删除重复项,甚至 Hashable
,它允许几乎恒定时间的查找。
一些与您想要的签名完全匹配的函数是:
nubOrdOn
from the containers 包裹
Data.Containers.ListUtils> nubOrdOn (\f -> (fooName f, fooAge f)) foos
hashNubOn
from the witherable 包裹
Witherable> hashNubOn (\f -> (fooName f, fooAge f)) foos
您可以通过搜索 Hoogle for (a -> b) -> [a] -> [a]
找到其他选项
如果你需要做很多这样的操作,你可能更愿意直接使用Map
或HashMap
。
给定一条像
这样的记录data Foo = Foo { fooName :: Text, fooAge :: Int, fooCity :: Text }
有了这些元素的列表,在这个假设的 removeDupBy
函数的模型上,是否有一个函数可以仅删除字段子集上的重复项?
foos =
[
Foo "john" 32 "London",
Foo "joe" 18 "New York",
Foo "john" 22 "Paris",
Foo "john" 32 "Madrid",
Foo "joe" 17 "Los Angeles",
Foo "joe" 18 "Berlin"
]
> removeDupBy (\(Foo f) -> (fooName, fooAge)) foos
[
Foo "john" 32 "London",
Foo "joe" 18 "New York",
Foo "john" 22 "Paris",
Foo "joe" 17 "Los Angeles"
]
我可以实现我自己的,但更喜欢使用一个来自成熟库的库,它可能性能更高,并且对边缘情况更有弹性。我正在考虑使用 nub
,但我不确定如何将实际的 Foo
元素映射到 nub
会过滤掉的元组 (fooName, fooAge)
。
您可以使用 nubBy:
Prelude Data.List> nubBy (\x y -> (fooName x, fooAge x) == (fooName y, fooAge y)) foos
[Foo {fooName = "john", fooAge = 32, fooCity = "London"},
Foo {fooName = "joe", fooAge = 18, fooCity = "New York"},
Foo {fooName = "john", fooAge = 22, fooCity = "Paris"},
Foo {fooName = "joe", fooAge = 17, fooCity = "Los Angeles"}]
(输出格式化以增强可读性)
因为你只处理字符串和数字,你可以使用 Ord
实例来有效地删除重复项,甚至 Hashable
,它允许几乎恒定时间的查找。
一些与您想要的签名完全匹配的函数是:
nubOrdOn
from the containers 包裹
Data.Containers.ListUtils> nubOrdOn (\f -> (fooName f, fooAge f)) foos
hashNubOn
from the witherable 包裹
Witherable> hashNubOn (\f -> (fooName f, fooAge f)) foos
您可以通过搜索 Hoogle for (a -> b) -> [a] -> [a]
如果你需要做很多这样的操作,你可能更愿意直接使用Map
或HashMap
。