使用linq对带有客户类密钥的字典进行分组

时间:2017-05-19 08:16:12

标签: linq dictionary group-by

我有一个要求,我必须在字典上进行分组,并将基于组的结果行输入另一个具有键,值对,值为List(位置)的字典。

下面的代码片段解释了我的问题陈述:

public class Positions
{
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public string Value3 { get; set; }
    public string Value4 { get; set; }
    public string Value5 { get; set; }
    public string Value6 { get; set; }
    public string Value7 { get; set; }
    public string Value8 { get; set; }
    public string Value9 { get; set; }
    public string Value10 { get; set; }
    public string Value11 { get; set; }
    public string Value12 { get; set; }
}

public struct PositionKey
{
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public string Value3 { get; set; }
    public string Value4 { get; set; }
    public string Value5 { get; set; }
    public string Value6 { get; set; }

    public override int GetHashCode()
    {
        return (Value1 != null ? Value1.GetHashCode() : 1)
               ^ (Value2 > 0 ? Value2.GetHashCode() : 1)
               ^ (Value3 != null ? Value3.GetHashCode() : 1)
               ^ (Value4 != null ? Value4.GetHashCode() : 1)
               ^ (Value5 != null ? Value5.GetHashCode() : 1)
               ^ (Value6 != null ? Value6.GetHashCode() : 1);
    }

    public override bool Equals(object obj)
    {
        PositionKey compositeKey = (PositionKey)obj;
        return Value1 == compositeKey.Value1
                 && Value2 == compositeKey.Value2
                 && Value3 == compositeKey.Value3
                 && Value4 == compositeKey.Value4
                 && Value5 == compositeKey.Value5
                 && Value6 == compositeKey.Value6;
    }
}


public struct GroupbyPositionKey
{
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public override int GetHashCode()
    {
        return (Value1 != null ? Value1.GetHashCode() : 1)
               ^ (Value2 > 0 ? Value2.GetHashCode() : 1);
    }

    public override bool Equals(object obj)
    {
        PositionKey compositeKey = (PositionKey)obj;
        return Value1 == compositeKey.Value1
                 && Value2 == compositeKey.Value2;
    }
}

public class program
{
    /*         
        Value1  Value2  Value3  Value4  Value5  Value6  Value7  Value8  Value9  Value10  Value11    Value12
        -------------------------------------------------------------------------------------------------
        v1      1       val1    val2    val3    val4    val5    val6    val7    val8     val9       val10
        v1      1       val2    val3    val4    val5    val6    val7    val8    val9     val10      val11
        v3      4       val3    val4    val5    val6    val7    val8    val9    val10    val11      val12
        v3      4       val4    val5    val6    val7    val8    val9    val10   val11    val12      val13
        v3      5       val5    val6    val7    val8    val9    val10   val11   val12    val13      val14
        v4      6       val6    val7    val8    val9    val10   val11   val12   val13    val14      val15
        v4      6       val7    val8    val9    val10   val11   val12   val13   val14    val15      val16
        v4      7       val8    val9    val10   val11   val12   val13   val14   val15    val16      val17
        v4      7       val9    val10   val11   val12   val13   val14   val15   val16    val17      val18


        Group by - Value1   Value2  Value3  Value4  Value5  Value6  Value7  Value8  Value9  Value10  Value11    Value12
        Get List of the rows after the grouping on the basis of group by Value1,Value2
     */
    public static void main()
    {
        Dictionary<PositionKey, Positions> dictPositons = new Dictionary<PositionKey, Positions>();

        Positions obj = new Positions();
        obj.Value1 = "v1";
        obj.Value2 = 1;
        obj.Value3 = "val1";
        obj.Value4 = "val2";
        obj.Value5 = "val3";
        obj.Value6 = "val4";
        obj.Value7 = "val5";
        // ........ and so on.. and so forth...for all the objects.

        /*
            I have a datatable as above and i am inserting the rows in the collection object of class <Positions> with respective key
            and add the same to the dictionary.
        */

        PositionKey key = new PositionKey();
        key.Value1 = "v1";
        key.Value2 = 1;
        key.Value3 = "val3";
        key.Value4 = "val4";
        key.Value5 = "val5";
        key.Value6 = "val6";

        if (!dictPositons.ContainsKey(key))
        {
            dictPositons.Add(key, obj);  // this dictionary would have the raw data which would have all the rows from the table as a dictionary collection
        }


        /*
         Now I have to create another dictionary which gives me a list of all the records by grouping on the basis 
         of the key <GroupbyPositionKey> which is nothing but <Value1,Value2>

        The resulting dictionary should look like Dictionary<GroupbyPositionKey,List<Positions>>
         */
        Dictionary<GroupbyPositionKey, List<Positions>> result = new Dictionary<GroupbyPositionKey, List<Positions>>();
        result = dictPositions.GroupBy(....);    // not sure how ? 
    }
}

在结果中,我想要另一个字典,其中key对象的值为value1,value2,value对象为List(Positions)。我不确定如何在字典中接近小组以获得所需的结果。

我已经通过手动循环遍历字典然后在新密钥的基础上选择并插入到另一个字典中来实现此结果。但我想知道是否有一种LINQ方式可以做到这一点,这将会更短。

1 个答案:

答案 0 :(得分:0)

GroupBy语句中,您需要创建一个新的GroupbyPositionKey类,然后使用ToDictionary方法选择您的密钥和列表

    Dictionary<GroupbyPositionKey, List<Positions>> result = dictPositons
        .GroupBy(x => new GroupbyPositionKey { Value1 = x.Key.Value1, Value2 = x.Key.Value2 })
        .ToDictionary(x => x.Key, x => x.Select(y => y.Value).ToList());