如何以最易读的方式使用 LanguageExt 在 C# 中构建嵌套的 HashMap?
How to build nested HashMap in C# using LanguageExt in a most-readable way?
在 .NET/C# 中,我有 IEnumerable<T>
类型的输入数据,T
具有一些我想用于查找的属性。
如何使用 LanguageExt 构建两级(也许三级)查找而不产生像这样难以阅读的代码:
var items = Range(1, 1000)
.Map(i => new
{
Number = i,
Section = (byte) (i % 10),
Text = $"Number is i"
}); // just some test data
HashMap<byte, HashMap<int, string>> lookup
= toHashMap(
from item in items
group item.Text by (item.Section, item.Number) into gInner
group gInner by gInner.Key.Section into gOuter
select ( gOuter.Key, toHashMap(gOuter.Map(_ => (_.Key.Number, _.Head()))) )
);
预期输出:使用 Section
作为外键、Number
作为内键和 Text
作为值的查找 hashmap。
我更喜欢使用 LINQ 语法的解决方案(可能更容易将其与转换/过滤/排序结合起来......)。
Language-ext has built-in extension methods 用于处理嵌套的 HashMap
和 Map
类型(最多四个嵌套级别):
因此,要查找类型:
HashMap<int, HashMap<string, DateTime>> lookup = ...;
var value = lookup.Find(123, "Hello");
您还可以添加:
lookup = lookup.AddOrUpdate(123, "Hello", value);
还有Remove
、MapRemoveT
、MapT
、FilterT
、FilterRemoveT
、Exists
、ForAll
、SetItemT
、TrySetItemT
和 FoldT
。
因此,回答您的具体问题:
var map = items.Fold(
HashMap<byte, HashMap<int, string>>(),
(s, item) => s.AddOrUpdate(item.Section, item.Number, item.Text));
如果你经常这样做,那么你可以将它概括为 Seq<(A, B, C)>
的扩展
public static HashMap<A, HashMap<B, C>> ToHashMap<A, B, C>(this Seq<(A, B, C)> items) =>
items.Fold(
HashMap<A, HashMap<B, C>>(),
(s, item) => s.AddOrUpdate(item.Item1, item.Item2, item.Item3));
我有同样的要求,这就是我将这些添加到 language-ext 的原因:)
在 .NET/C# 中,我有 IEnumerable<T>
类型的输入数据,T
具有一些我想用于查找的属性。
如何使用 LanguageExt 构建两级(也许三级)查找而不产生像这样难以阅读的代码:
var items = Range(1, 1000)
.Map(i => new
{
Number = i,
Section = (byte) (i % 10),
Text = $"Number is i"
}); // just some test data
HashMap<byte, HashMap<int, string>> lookup
= toHashMap(
from item in items
group item.Text by (item.Section, item.Number) into gInner
group gInner by gInner.Key.Section into gOuter
select ( gOuter.Key, toHashMap(gOuter.Map(_ => (_.Key.Number, _.Head()))) )
);
预期输出:使用 Section
作为外键、Number
作为内键和 Text
作为值的查找 hashmap。
我更喜欢使用 LINQ 语法的解决方案(可能更容易将其与转换/过滤/排序结合起来......)。
Language-ext has built-in extension methods 用于处理嵌套的 HashMap
和 Map
类型(最多四个嵌套级别):
因此,要查找类型:
HashMap<int, HashMap<string, DateTime>> lookup = ...;
var value = lookup.Find(123, "Hello");
您还可以添加:
lookup = lookup.AddOrUpdate(123, "Hello", value);
还有Remove
、MapRemoveT
、MapT
、FilterT
、FilterRemoveT
、Exists
、ForAll
、SetItemT
、TrySetItemT
和 FoldT
。
因此,回答您的具体问题:
var map = items.Fold(
HashMap<byte, HashMap<int, string>>(),
(s, item) => s.AddOrUpdate(item.Section, item.Number, item.Text));
如果你经常这样做,那么你可以将它概括为 Seq<(A, B, C)>
public static HashMap<A, HashMap<B, C>> ToHashMap<A, B, C>(this Seq<(A, B, C)> items) =>
items.Fold(
HashMap<A, HashMap<B, C>>(),
(s, item) => s.AddOrUpdate(item.Item1, item.Item2, item.Item3));
我有同样的要求,这就是我将这些添加到 language-ext 的原因:)