Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何按(对象的)列表键对字典进行分组?_.net_Linq_List_Dictionary - Fatal编程技术网

.net 如何按(对象的)列表键对字典进行分组?

.net 如何按(对象的)列表键对字典进行分组?,.net,linq,list,dictionary,.net,Linq,List,Dictionary,我有字典(对象列表,整数),需要按键对字典进行分组 例如: Dictionary (0) = Key: {List(12, "SomeString", 3)} Value: 54 Dictionary (1) = Key: {List(8, "SomeAnotherString", 3)} Value: 6 Dictionary (2) = Key: {List(12, "SomeString", 3)} Value: 15 如何获取此词典的外观: Dictionary (0) = Key

我有
字典(对象列表,整数)
,需要按键对字典进行分组

例如:

Dictionary (0) = Key: {List(12, "SomeString", 3)} Value: 54

Dictionary (1) = Key: {List(8, "SomeAnotherString", 3)} Value: 6

Dictionary (2) = Key: {List(12, "SomeString", 3)} Value: 15
如何获取此
词典
的外观:

Dictionary (0) = Key: {List(12, "SomeString", 3)} Value: 54, 15

Dictionary (1) = Key: {List(8, "SomeAnotherString", 3)} Value: 6

我正在用C#给出一个解决方案,但将其转换为VB.NET对您来说应该不是问题

此外,我假设列表(对象)中存在的对象数始终为3,并且按int、string、int类型的顺序排列

以下是我对你问题的解决方案

  • 创建一个新类,称为“MyList”,它继承自(对象的)列表
  • 重写“MyList”类中的Equals方法,并在该方法中通过检查每个元素来检查传递的列表是否与当前列表相同
  • 将原始字典创建为key=“MyList”,value=int
  • 创建一个新字典,如key=“MyList”,value=List(整型)
  • 创建一个方法,该方法将调用重写的equals方法,如果返回false,则添加一个新的键/值,如果返回true,则将该值添加到该键
  • 下面是完整的代码

        Dictionary<MyList, List<int>> newOtherDict;
    
        private void button1_Click(object sender, EventArgs e)
        {
            //Dummy data for testing
            Dictionary<MyList, int> myDict = new Dictionary<MyList, int>();
            myDict.Add(new MyList() {1, "SomeString", 3 }, 1);
            myDict.Add(new MyList() { 1, "SomeOtherString", 3 }, 12);
            myDict.Add(new MyList() { 1, "SomeString", 3 }, 123);
    
            //This dictionary will contain the consolidated values
            newOtherDict = new Dictionary<MyList, List<int>>();
    
            for (int i = 0; i < myDict.Count; i++)
            {
                AddOrAppendToNewDict(myDict.ElementAt(i));
            }
        }
    
        private void AddOrAppendToNewDict(KeyValuePair<MyList, int> keyValue)
        {
            var foundPair = newOtherDict.Where(x => x.Key.Equals(keyValue.Key));
    
            if (foundPair.Count() == 0)
            {
                newOtherDict.Add(keyValue.Key, new List<int>() { keyValue.Value });
            }
            else
            {
                foundPair.First().Value.Add(keyValue.Value);
            }
        }
    
        class MyList : List<object>
        {
            public override bool Equals(object obj)
            {
                List<object> toCompareClass = obj as List<object>;
    
                if (Convert.ToInt32(this[0]) == Convert.ToInt32(toCompareClass[0]) &&
                    Convert.ToInt32(this[2]) == Convert.ToInt32(toCompareClass[2]) &&
                    this[1].ToString() == toCompareClass[1].ToString())
                    return true;
    
                return false;
            }
        }
    
    Dictionary-newOtherDict;
    私有无效按钮1\u单击(对象发送者,事件参数e)
    {
    //试验用虚拟数据
    Dictionary myDict=新字典();
    Add(new MyList(){1,“SomeString”,3},1);
    Add(new MyList(){1,“SomeOtherString”,3},12);
    Add(new MyList(){1,“SomeString”,3},123);
    //此词典将包含合并值
    newOtherDict=新字典();
    for(int i=0;ix.Key.Equals(keyValue.Key));
    if(foundPair.Count()==0)
    {
    添加(keyValue.Key,new List(){keyValue.Value});
    }
    其他的
    {
    foundPair.First().Value.Add(keyValue.Value);
    }
    }
    类MyList:List
    {
    公共覆盖布尔等于(对象对象对象)
    {
    List to CompareClass=对象作为列表;
    if(Convert.ToInt32(此[0])==Convert.ToInt32(to比较类[0])&&
    Convert.ToInt32(此[2])==Convert.ToInt32(to比较类[2])&&
    此[1]。ToString()==toCompareClass[1]。ToString()
    返回true;
    返回false;
    }
    }
    
    我希望这能解决你的问题

    问候,


    萨马尔

    我想你不明白字典是怎么工作的。 字典的值通过其唯一键进行访问。在内部,使用键生成的哈希代码查找它们。要正常工作,哈希代码需要几个属性:

    • 比较为相等的两个对象必须具有相同的哈希代码

    • 如果可变对象生成依赖于其可变状态的哈希代码,则不应将其用作字典中的键。原因很简单:如果您将这样一个对象放入哈希表并对其进行变异,您将无法再次找到它

    哈希代码由函数生成,该函数可能被任何类型重写。 您使用
    列表(对象)
    作为键值<代码>列表(对象)不覆盖
    GetHashCode
    。它使用对象类型的默认实现。尽管此实现满足所述的要求,但它肯定不是您想要的

    我注意到,您尝试用作键的列表总是具有相同的结构:一个整数、一个字符串和另一个整数<代码>列表(对象)不是键的好选择。但也许您可以创建一个可用作键的类型:

    Public Class MyKey
        Private ReadOnly _firstValue As Integer
        Private ReadOnly _secondValue As String
        Private ReadOnly _thirdValue As Integer
    
        Public Sub New(firstValue As Integer, secondValue As String, thirdValue As Integer)
            _firstValue = firstValue
            _secondValue = secondValue
            _thirdValue = thirdValue
        End Sub
    
        Public ReadOnly Property FirstValue As Integer
            Get
                Return _firstValue
            End Get
        End Property
    
        Public ReadOnly Property SecondValue As String
            Get
                Return _secondValue
            End Get
        End Property
    
        Public ReadOnly Property ThirdValue As Integer
            Get
                Return _thirdValue
            End Get
        End Property
    
        Public Overloads Function GetHashCode() As Integer
            Dim hashCode As Integer = 31
            hashCode = hashCode + 17 * _firstValue
            hashCode = hashCode + 17 * _secondValue.GetHashCode()
            hashCode = hashCode + 17 * _thirdValue
    
            Return hashCode
        End Function
    
        Public Overloads Function Equals(obj As Object) As Boolean
            If TypeOf obj Is MyKey Then
                Dim other As MyKey = CType(obj, MyKey)
                Return _firstValue = other._firstValue And
                       _secondValue = other._secondValue And
                       _thirdValue = other._thirdValue
            Else
                Return False
            End If
        End Function
    End Class
    
    此类型可用于字典键。它生成正确的哈希代码并重写以比较内容而不是引用。此外,它是不可变的,以确保哈希代码永远不会更改

    字典需要唯一的键。由于键不是唯一的,所以值的类型必须是List(整数)。添加值需要一些额外的工作。首先,您必须检查字典中是否已经存在密钥。如果没有,请创建新条目:

    Dim dictionary As New Dictionary(Of MyKey, List(Of Integer))
    Add(dictionary, New MyKey(12, "SomeString", 3), 54)
    Add(dictionary, New MyKey(8, "SomeAnotherString", 3), 6)
    Add(dictionary, New MyKey(12, "SomeString", 3), 15)
    
    Public Sub Add(dictionary As Dictionary(Of MyKey, List(Of Integer)), key As MyKey, value As Integer)
        Dim list As List(Of Integer) = Nothing
        If Not dictionary.TryGetValue(key, list) Then
            list = New List(Of Integer)()
            dictionary.Add(key, list)
        End If
    
        list.Add(value)
    End Sub
    

    如果字典中的键不能生成正确的哈希代码,并且没有等式检查器,那又有什么意义呢?另一点是字典不能每个键有多个项。值:54,15可以是一个
    列表(整数)
    。正如@dasblinkenlight所说,将列表作为键几乎肯定不是你想要的。也许你期望这样的事情:[12]=>54,15;“SomeString”=>54,15;8 => 6?