.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类型的顺序排列 以下是我对你问题的解决方案
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?