LINQ 魔术,无需研究每个项目即可在集合中查找多个项目?
LINQ magic for finding multiple items in a collection without researching for each one?
更新:字典解决方案很棒,除非要查找的事物的数量与列表中的事物数量相比显得苍白无力。我应该事先说明。
假设你有数组:
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 方法可以实现相同的结果而不会受到效率问题的影响?
如果您希望能够根据 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...
要有效地搜索一组键值对,您应该将它们放入字典中,而不是数组中:
var lookup = arr.ToDictionary(pair => pair.Item1, pair => pair.Item2);
这使您可以非常快速地搜索任一值:
var s1 = lookup["1"];
var s2 = lookup["2"];
如果您只搜索极少数项目,并且没有特别大的数据集,那么您最好只进行多次线性搜索,但随着搜索次数的增加如果你在做上升,你就必须花更多的时间来创建查找。
另请注意,在您提供的两个解决方案中,它们对性能的影响几乎相同。执行一个循环所需的时间是其他两个循环的两倍,结果是相同的工作量。使用第二个解决方案的唯一真正原因是,如果您拥有的序列不能可靠地多次枚举(也许它代表数据库查询,导致副作用,每次迭代都不会产生相同的值,等等)。
更新:字典解决方案很棒,除非要查找的事物的数量与列表中的事物数量相比显得苍白无力。我应该事先说明。
假设你有数组:
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 方法可以实现相同的结果而不会受到效率问题的影响?
如果您希望能够根据 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...
要有效地搜索一组键值对,您应该将它们放入字典中,而不是数组中:
var lookup = arr.ToDictionary(pair => pair.Item1, pair => pair.Item2);
这使您可以非常快速地搜索任一值:
var s1 = lookup["1"];
var s2 = lookup["2"];
如果您只搜索极少数项目,并且没有特别大的数据集,那么您最好只进行多次线性搜索,但随着搜索次数的增加如果你在做上升,你就必须花更多的时间来创建查找。
另请注意,在您提供的两个解决方案中,它们对性能的影响几乎相同。执行一个循环所需的时间是其他两个循环的两倍,结果是相同的工作量。使用第二个解决方案的唯一真正原因是,如果您拥有的序列不能可靠地多次枚举(也许它代表数据库查询,导致副作用,每次迭代都不会产生相同的值,等等)。