LINQ 魔法,用于在集合中查找多个项目,而无需研究每个项目

本文关键字:项目 用于 魔法 集合 查找 LINQ | 更新日期: 2023-09-27 18:36:12

UPDATE:字典解决方案很棒,除非要查找的事物数量与列表中的事物数量相比相形见绌。 我应该提前说明这一点。

假设您有阵列:

var arr = { 
  Tuple.Create("1", "won"),
  Tuple.Create("4", "fo"),
  Tuple.Create("3", "twee", 
  Tuple.Create("2", "too") 
  // ...
  // ...and many more entires...
};

并且您被告知要找到字符串"1"和"2",因此您这样做:

string s1 = arr.First(c => c.Item1 == "1").Item2;
string s2 = arr.First(c => c.Item2 == "2").Item2;

但在回顾中,请注意您搜索了同一个数组两次,因此将其更改为:

string s1;
string s2;
bool founds1 = false;
bool founds2 = false;
foreach(int i; i < arr.Length; i++)
{
  if(arr[i] == "1")
  {
    s1 = arr[i].Item2;
    founds1 = true;
  }
  if(arr[i] == "2")
  {
    s2 = arr[i].Item2
    founds2 = true;
  }
  if(founds1 && founds2)
    break;
}

是否有任何 LINQ 方法可以在不受效率问题影响的情况下实现相同的结果?

LINQ 魔法,用于在集合中查找多个项目,而无需研究每个项目

为了有效地搜索键值对的集合,您应该将它们放入字典中,而不是数组中:

var lookup = arr.ToDictionary(pair => pair.Item1, pair => pair.Item2);

这使您可以非常快速地搜索任一值:

var s1 = lookup["1"];
var s2 = lookup["2"];
如果您只搜索

非常少量的项目,并且没有特别大的数据集,那么最好只进行多个线性搜索,但随着您正在执行的搜索数量的增加,您必须从前期花费时间来创建查找中获得更多收益。

另请注意,在您提供的两个解决方案中,它们的性能影响几乎相同。 执行一个循环所需的时间是其他两个循环的两倍,则会导致相同的工作量。 使用第二个解决方案的唯一真正原因是,如果您拥有的序列无法可靠地多次枚举(可能它表示数据库查询,导致副作用,在每次迭代中不产生相同的值等)。

如果您希望

能够根据Tuple的第一部分查找项目,则使用了错误的数据结构。

切换到使用Dictionary<string, string>,可以使用索引器,而无需枚举整个集合:

var dict = new Dictionary<string, string>
{
    { "1", "won" },
    { "4", "fo" },
    { "3", "twee" },
    { "2", "too" }
};
if(dict.ContainsKey("1"))
{
    founds1 = true;
    s1 = dict["1"];
}
// And so on...