Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.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
C# 使用C中的dictionary将某些自定义类属性用作同一类中另一个属性(形式为值)的唯一键_C#_Linq_Dictionary_Data Structures - Fatal编程技术网

C# 使用C中的dictionary将某些自定义类属性用作同一类中另一个属性(形式为值)的唯一键

C# 使用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

我有一个类类型say ValueSetting,如下所示,我正在尝试迭代List,以便对于列表中所有常见的param1、param2、param3条目,我必须对每个param4执行特定的操作。让我解释一下。在下表中,带有红色箭头标记param1、param2、param3的条目应该是类似于param4500600的list的键。因此,要巩固它们

10,foo,abc=>500600

20,boo,abc=>500600

30,foo,abc=>500

那么,这是我可以放在字典中的东西吗,用param1,param2,param3作为List的键?这是怎么做到的?还是有更好的方法来存储它们而不是字典


可以使用您询问的方式来构造数据。从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)