【问题标题】:How to build nested HashMap in C# using LanguageExt in a most-readable way?如何以最易读的方式使用 LanguageExt 在 C# 中构建嵌套的 HashMap?
【发布时间】:2019-10-10 08:30:18
【问题描述】:

在 .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 语法的解决方案(也许可以更轻松地将其与转换/过滤/排序结合起来......)。

【问题讨论】:

  • 能否提供输入/输出数据描述/示例?回答你的问题会更容易。
  • 问题已更新。注意:SectionNumber 应该被视为不相关的属性。

标签: c# linq hashmap ienumerable language-ext


【解决方案1】:

Language-ext has built-in extension methods 用于处理嵌套的HashMapMap 类型(最多嵌套四层):

所以,要查找一个类型:

HashMap<int, HashMap<string, DateTime>> lookup = ...;

var value = lookup.Find(123, "Hello");

您还可以添加:

lookup = lookup.AddOrUpdate(123, "Hello", value);

还有RemoveMapRemoveTMapTFilterTFilterRemoveTExistsForAllSetItemTTrySetItemTFoldT

所以,回答你的具体问题:

var map = items.Fold(
            HashMap<byte, HashMap<int, string>>(), 
            (s, item) => s.AddOrUpdate(item.Section, item.Number, item.Text));

如果你经常这样做,那么你可以将它概括为Seq&lt;(A, B, C)&gt;的扩展

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));

我有同样的要求,这就是我将这些添加到语言扩展的原因:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多