簡體   English   中英

如何使用 linq 將平面列表轉換為多級查找?

[英]How to convert flat list to multi-level lookups using linq?

我有包含三個鍵的對象列表,我想將其轉換為三個級別的查找(或字典):

class MyClass
{
    public int Key1;
    public int Key2;
    public int Key3;
    public float Value;
}
...

IEnumerable<MyClass> table = new List<MyClass>()
{
    new MyClass(){Key1 = 11, Key2 = 21, Key3 = 31, Value = 1},
    new MyClass(){Key1 = 11, Key2 = 21, Key3 = 32, Value = 2},
    new MyClass(){Key1 = 11, Key2 = 22, Key3 = 31, Value = 3},
    new MyClass(){Key1 = 11, Key2 = 23, Key3 = 33, Value = 4},
    new MyClass(){Key1 = 12, Key2 = 21, Key3 = 32, Value = 5},
    new MyClass(){Key1 = 12, Key2 = 22, Key3 = 31, Value = 6}

};

我希望結果屬於以下類型:

ILookup<int, ILookup<int, Dictionary<int, float>>>

或者

Dictionary<int, Dictionary<int, Dictionary<int, float>>>

我試過:

ILookup<int, MyClass> level1 = table.ToLookup(i => i.Key1, i => i);
ILookup<int, ILookup<int, MyClass>> level2 = level1.ToLookup(
    i => i.Key, i => i.ToLookup(j => j.Key2, j => j));
ILookup<int, ILookup<int, Dictionary<int, float>>> level3 = ?

,但我卡在第三級。 這可能是一個騙局,但我正在尋找的可能是關於具有父子關系的對象列表的大量問題。 [1] [2] [3] [4]

它有點眼花繚亂,根本不可讀,但這會讓你理清頭緒:

ILookup<int, ILookup<int, Dictionary<int, float>>> result = table
                .ToLookup(i => i.Key1)
                .ToLookup(i => i.Key, i => i.ToLookup(j => j.Key2)
                .ToLookup(x => x.Key, x => x.ToDictionary(y => y.Key3, y => y.Value)));

如果您確定 {Key1, Key2, Key3} 的每個組合都是唯一的,您可以創建一個 Dictionary。 從字典中獲取值將返回一個浮點數。

如果可能存在{Key1, Key2, Key3} 的重復組合,則需要創建一個LookupTable。 提取返回具有此鍵組合的所有原始值的序列。

為此,您需要使用 keySelector 和 ElementSelector 重載 Enumerable.ToLookup重載 Enumerable.ToDictionary

  • 密鑰: new {Key1, Key2, Key3}
  • 元素: Value

所以:

IEnumerable<MyClass> table = ...
var lookupTable = table.ToLookup(

    // parameter keySelector: for every object of MyClass take the keys:
    myObject => new
    {
       Key1 = myObject.Key1,
       Key2 = myObject.Key2,
       Key3 = myObject.Key3,
    },

    // parameter elementSelector: for every object of MyClass take the Value
    myObject => myObject.Value);

ToDictionary 類似:

var dictionary = table.ToLookup(myObject => new
    {
       Key1 = myObject.Key1,
       Key2 = myObject.Key2,
       Key3 = myObject.Key3,
    },
    myObject => myObject.Value);

用法:

var keyToLookup = new 
{
    Key1 = 7,
    Key2 = 14,
    Key3 = 42,
};

float lookedUpValue = dictionary[keyToLookup];
IEnumerable<lookedUpValues = lookupTable[keyToLookup];

簡單的來吧!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM