C# 通过集合的某个值从集合中获取元组?

C# 通过集合的某个值从集合中获取元组?,c#,data-structures,collections,tuples,C#,Data Structures,Collections,Tuples,是否有一种方法可以仅通过元组的一个值从集合中获取元组?例如,当我使用这个元组结构时: public struct Tuple<T1, T2> { public readonly T1 Item1; public readonly T2 Item2; public Tuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2;} } 公共结构元组{ 公共只读T1项1; 公共只读T2项2; 公共元组(T1项1

是否有一种方法可以仅通过元组的一个值从集合中获取元组?例如,当我使用这个元组结构时:

public struct Tuple<T1, T2> {
    public readonly T1 Item1;
    public readonly T2 Item2;
    public Tuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2;} 
}
公共结构元组{
公共只读T1项1;
公共只读T2项2;
公共元组(T1项1,T2项2){item1=item1;item2=item2;}
}

是否有一种方法可以获取具有特定项(Item1或Item2)的所有元组。我考虑过某种HashMap,因为在元组列表中循环并检查每个元组是否匹配对于大型数据集来说效率很低。

如果您有这样一个列表:

List<Tuple<T1, T2>> mylist;
var myValue = mylist.FirstOrDefault((t) => t.Item1 == "MyKey");

然而,我应该补充一点,这不是一个真正好的设计。有关详细信息,请参见注释,但在我看来,元组通常不适合于严肃的任务,因为元素没有命名。数据结构中的未命名元素越多,代码就越难阅读。我总是用字典来完成这样的任务。在这种情况下,我认为您不应该不情愿使用字典。

如果您有
Tuple
对象列表,您可以使用LINQ通过指定所需条件来获得包含所需对象的新列表。下面是一个使用
Tuple
对象的示例:

 List<Tuple<int, string>> originalList = new List<Tuple<int, string>>();

 originalList.Add(new Tuple<int, string>(1, "Tom"));
 originalList.Add(new Tuple<int, string>(2, "Jim"));
 originalList.Add(new Tuple<int, string>(3, "Bob"));
 originalList.Add(new Tuple<int, string>(1, "Ted"));
 originalList.Add(new Tuple<int, string>(3, "Hal"));
 originalList.Add(new Tuple<int, string>(1, "Zim"));
 originalList.Add(new Tuple<int, string>(3, "Jed"));

List<Tuple<int, string>> filteredList = originalList.Where(t => t.Item1 == 3).ToList();

// filteredList contains these:
// (3, "Bob")
// (3, "Hal")
// (3, "Jed")

List<Tuple<int, string>> anotherFilteredList = originalList.Where(t => t.Item2.StartsWith("J")).ToList();

// anotherFilteredList contains these:
// (2, "Jim")
// (3, "Jed")
List originalList=new List();
添加(新元组(1,“Tom”);
添加(新元组(2,“Jim”);
添加(新元组(3,“Bob”);
添加(新元组(1,“Ted”);
添加(新元组(3,“Hal”);
添加(新元组(1,“Zim”);
添加(新元组(3,“Jed”);
List filteredList=originalList.Where(t=>t.Item1==3.ToList();
//filteredList包含以下内容:
//(3,“鲍勃”)
//(3,“Hal”)
//(3,“杰德”)
列出另一个filteredlist=originalList.Where(t=>t.Item2.StartsWith(“J”)).ToList();
//另一个FilteredList包含以下内容:
//(2,“吉姆”)
//(3,“杰德”)

不幸的是,.Net似乎不包含任何类型的节省空间的集合类,这些集合类基于从存储的对象中提取的键。
KeyedCollection
类具有正确的接口,但在内部分别存储键和值。我建议您需要创建自己的类,实现
ILookup
,但允许动态修改(不幸的是,内置的
Lookup
类不允许动态修改)。

您必须在某种收集中跟踪它们。好的,收集它们的好数据结构是什么。拥有一个字典,每个项都有一个键,而tuple对象作为一个值,这在存储方面感觉非常低效。您为什么要编写自己的
tuple
而不是使用.NET的
tuple
?您还应该真正避免可变结构。@Servy.NETs Tuple是一个类,对吗?OP难道不想要结构的ValueTuple吗?@maccettura我怀疑他们首先需要一个值类型,但如果他们确实有一个很好的理由在这里需要一个值类型,那么是的,在.NET中有一个引用和值类型的元组版本。谢谢@BlueMonkMN。这是一个有效的解决方案。我猜LINQ会遍历所有条目并检查匹配项,对吗?我想知道是否有可能通过某种散列(HashMap或其他)来解决这个问题,因为它比在列表中循环更有效。无论如何,好答案,如果以后没有其他答案,我会接受:)对不起,我是说HashMap不是HashSetHashMap的.Net等价物是
字典
。不过,我认为我们不应该鼓励OP编写自己的元组结构,也许可以在你的answer@maccettura完成。使用自定义比较器进行排序列表和二进制搜索如何?@BlueMonkMN如果您检查源代码,
SortedList
保留一个排序的键数组和一个单独的值数组,并在每次添加时复制它们,因此效率不高,特别是如果您的键是大值类型,我说的不是
SortedList
,而是排序的
列表