我有一个收藏品。我想选择符合2个条件的值。
var a;
var b;
foreach(SomeObject so in collection)
{
if(so.Value == something)
{
a = so;
// break if b is not null.
}
else if(so.Value == somethingElse)
{
b = so;
// break if a is not null
}
}
是否可以使用linq迭代仅对集合执行上述操作一次?如果我们可以使用这个事实,那么只有一个值的东西和一个值的东西。
答案 0 :(得分:3)
此解决方案将列表缩小为两个元素,然后从那里开始。使用Take(2)
因此只搜索集合,直到找到两个值。
var matches = collection.Where(x => x.Value == something || x.Value == somethingElse)
.Take(2)
.ToList();
var a = matches.Single(x => x.Value == something);
var b = matches.Single(x => x.Value == somethingElse);
答案 1 :(得分:2)
你需要这样的东西:
var a = collection.OfType<YourCollectionElementType>().FirstOrDefault(i=>i.Equals(something));
var b = collection.OfType<YourCollectionElementType>().FirstOrDefault(i=>i.Equals(somethingelse));
您的收藏集应至少实现IEnumerable
以便能够使用此代码。
这取决于您的收藏类型。如果它实现了通用IEnumerable<T>
,说它是List<YourCollectionElementType>
或数组YourCollectionElementType[]
,那么您不需要使用OfType<T>
,即
var a = collection.FirstOrDefault(i=>i.Equals(something));
var b = collection.FirstOrDefault(i=>i.Equals(somethingelse));
如果您的收藏集不包含该值,则a
和/或b
会获得null
个值。
实际上你可以在MSDN中阅读所有这些内容。如果你尝试,LINQ并不难学 例如:
修改强>
在您的评论中,您说确保只有一个值。你需要两个独立的变量是非常重要的吗?你可以像这样获得现值:
object thevalue = collection.FirstOrDefault(i => i == something || i == somethingelse);
修改强>
实际上,我会保留你的循环,只是添加了这样一行:
SomeObject a;
SomeObject b;
foreach(SomeObject so in collection)
{
if(so.Value == something)
a = so;
else if(so.Value == somethingElse)
b = so;
if(a!=null && b!=null)
break;
}
如果只有一个值,那么
SomeObject a;
SomeObject b;
foreach(SomeObject so in collection)
{
if(so.Value == something)
{
a = so;
break;
}
else if(so.Value == somethingElse)
{
b = so;
break;
}
}
答案 2 :(得分:2)
var relevant =
from so in l where so.Value == something || so.Value == somethingElse
group so by so.Value == something into grp
select new {ForA = grp.Key, SO = grp.First()};
foreach(var bit in relevant)
if(bit.ForA)
a = bit.SO;
else
b = bit.SO;
它可以获得一些针对某些来源的东西,因为只检索了两个项目,但是如果针对内存中的一个集合,我将保留你所拥有的,但添加一个catch以便一旦你设置了{{ 1}}和a
,你停止循环而不是不必要地检查集合。
答案 3 :(得分:1)
你可以这样做:
collection
.Select(x => x.Value == something
? () => a = x
: (x.Value == somethingElse
? () => b = x
: (Action)null))
.Where(x => x != null)
.ToArray()
.ForEach(x => x());
我测试了这段代码并且它有所作为。
如果集合在某个地方的某个数据库上,那么我建议:
collection
.Where(x => x.Value == something || x.Value == somethingElse)
.ToArray()
.Select(x => x.Value == something
? () => a = x
: (x.Value == somethingElse
? () => b = x
: (Action)null))
.Where(x => x != null)
.ToArray()
.ForEach(x => x());
答案 4 :(得分:0)
当然可以,但我不推荐它。你现在已经拥有循环它会更清晰。
如果你真的想知道怎么做,你可以这样做:
class SomeObject
{
public string Value { get; set; }
}
var items = new[]
{
new SomeObject { Value = "foo" },
new SomeObject { Value = "bar" },
new SomeObject { Value = "baz" },
};
var something = "foo";
var somethingElse = "baz";
var result = items.Aggregate(
Tuple.Create(default(SomeObject), default(SomeObject)),
(acc, item) => Tuple.Create(
item.Value == something ? item : acc.Item1,
item.Value == somethingElse ? item : acc.Item2
)
);
// result.Item1 <- a == new SomeObject { Value = "foo" }
// result.Item2 <- b == new SomeObject { Value = "baz" }
答案 5 :(得分:0)
不确定如果我理解您的问题,但假设Something
和SomethingElse
是值类型并且在运行时之前已知,则可以在下面的一个语句中执行以下操作。
var FindItems = new[]
{
new SomeObject { Value = "SomethingElse" }
};
var CollectionItems = new[]
{
new SomeObject { Value = "Something" },
new SomeObject { Value = "SomethingElse" }
};
var qSomeObject = CollectionItems
.Where(c => FindItems.Any(x => c.Value == x.Value));