C# 使用C中的dictionary将某些自定义类属性用作同一类中另一个属性(形式为值)的唯一键
我有一个类类型say ValueSetting,如下所示,我正在尝试迭代ListC# 使用C中的dictionary将某些自定义类属性用作同一类中另一个属性(形式为值)的唯一键,c#,linq,dictionary,data-structures,C#,Linq,Dictionary,Data Structures,我有一个类类型say ValueSetting,如下所示,我正在尝试迭代List,以便对于列表中所有常见的param1、param2、param3条目,我必须对每个param4执行特定的操作。让我解释一下。在下表中,带有红色箭头标记param1、param2、param3的条目应该是类似于param4500600的list的键。因此,要巩固它们 10,foo,abc=>500600 20,boo,abc=>500600 30,foo,abc=>500 那么,这是我可以放在字典中的东西吗,用par
可以使用您询问的方式来构造数据。从MSDN: ToLookup方法返回一个查找,一个一对多的映射字典 值集合的键。查找不同于字典, 它执行键到单个值的一对一映射 要使用ToLookup方法创建查找,我们应定义: 具有重写的GetHashCode和Equals方法的键类;这个关键类将定义如何对输入数据进行分组; 用于从输入数据创建密钥的密钥选择器; 元素选择器,用于选择相应键的值。 第一种方法:使用匿名类型作为密钥 我们可以将其用作键来创建查找。匿名类型自动实现GetHashCode和Equals。从MSDN: 因为匿名类型上的Equals和GetHashCode方法是 根据的Equals和GetHashCode方法定义 属性,相同匿名类型的两个实例只有在 它们的所有性质都是相同的 以下是如何使用匿名类型作为密钥创建查找:
var list = new List<ValueSetting>
{
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 30, param2 = "foo", param3 = "abc", param4 = 500},
};
var lookup = list.ToLookup(
vs => new {vs.param1, vs.param2, vs.param3}, // Group key.
vs => vs.param4); // Group values.
foreach (var item in lookup)
{
Console.WriteLine("{0} => ({1})", item.Key, string.Join(", ", item.Select(i => i)));
}
然后使用这个密钥类,我们可以创建一个查找:
如果要从方法返回查找,或将其作为参数传递给另一个方法,或将其作为类的属性存储,以及在其他情况下创建查找时必须在创建查找的方法之外使用,则可以使用此方法。似乎可以使用以下方法:
var list = new List<ValueSetting>
{
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 30, param2 = "foo", param3 = "abc", param4 = 500},
};
var grouped = list.GroupBy(x => new { x.param1, x.param2, x.param3 });
foreach (var grp in grouped)
{
Console.WriteLine($"{grp.Key} => ({string.Join(", ", grp.Select(x => x.param4))})");
}
输出:
啊,托卢库普的用法很好。我认为这比在这里使用GroupBy要好。
public class Key
{
public int param1;
public string param2;
public string param3;
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
Key other = (Key) obj;
Key other = (Key) obj;
return param1 == other.param1 &&
string.Equals(param2, other.param2) &&
string.Equals(param3, other.param3);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = param1;
hashCode = (hashCode * 397) ^ (param2 != null ? param2.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (param3 != null ? param3.GetHashCode() : 0);
return hashCode;
}
}
}
var list = new List<ValueSetting>
{
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 30, param2 = "foo", param3 = "abc", param4 = 500},
};
ILookup<Key, int> lookup = list.ToLookup(
vs => new Key {param1 = vs.param1, param2 = vs.param2, param3 = vs.param3}, // Group key.
vs => vs.param4); // Group values.
foreach (IGrouping<Key, int> item in lookup)
{
Console.WriteLine("{0}, {1}, {2} => ({3})",
item.Key.param1, item.Key.param2, item.Key.param3,
string.Join(", ", item.Select(i => i)));
}
var list = new List<ValueSetting>
{
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 500},
new ValueSetting {param1 = 10, param2 = "foo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 20, param2 = "boo", param3 = "abc", param4 = 600},
new ValueSetting {param1 = 30, param2 = "foo", param3 = "abc", param4 = 500},
};
var grouped = list.GroupBy(x => new { x.param1, x.param2, x.param3 });
foreach (var grp in grouped)
{
Console.WriteLine($"{grp.Key} => ({string.Join(", ", grp.Select(x => x.param4))})");
}
var grouped = list
.GroupBy(x => new { x.param1, x.param2, x.param3 })
.Select(grp => new { grp.Key, param4 = grp.Select(x => x.param4) });
foreach (var grp in grouped)
{
Console.WriteLine($"{grp.Key} => ({string.Join(", ", grp.param4)})");
}
{ param1 = 10, param2 = foo, param3 = abc } => (500, 600)
{ param1 = 20, param2 = boo, param3 = abc } => (500, 600)
{ param1 = 30, param2 = foo, param3 = abc } => (500)