Как построить вложенный HashMap в C #, используя LanguageExt наиболее читабельным способом? - PullRequest
0 голосов
/ 10 октября 2019

В .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 в качестве значения.

Я предпочитаю решения, использующие синтаксис LINQ (возможно, облегчая объединение этого с преобразованием / фильтрацией / упорядочением ...).

1 Ответ

0 голосов
/ 10 октября 2019

Это решение без LINQ.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{

    public static void Main()
    {
        Console.WriteLine("Hello World");

        var items = Enumerable.Range(1, 100)
            .Select(i => new 
                 {
                   Number = i, 
                   Section = (byte) (i % 10), 
                   Text = "Number is " + i
                 }); // just some test data

        foreach(var item in items)
            Console.WriteLine("Num:"+item.Number+",Sect:"+item.Section+",Text:"+item.Text);

        Dictionary<byte, Dictionary<int, string>> lookup = 
            new Dictionary<byte, Dictionary<int, string>>();

        foreach(var item in items) {

            byte section = (byte) (item.Number % 10);
            Dictionary<int, string> secondLvlLookup = null;

            if (lookup.ContainsKey(section)) {
                secondLvlLookup = lookup[section];
            } else {
                secondLvlLookup = new Dictionary<int, string>();
                lookup[section] = secondLvlLookup;
            }

            secondLvlLookup[item.Number] = item.Text;           
        }

        Console.WriteLine(lookup[1][11]);
    }
}

, чтобы сделать его немного короче, мы можем получить secondLvlLookup как

Dictionary<int, string> secondLvlLookup = lookup.ContainsKey(section) ? lookup[section] : new Dictionary<int, string>();
lookup[section] = secondLvlLookup;
...