我有ICollection<SomeClass>
。
public class SomeClass
{
public string Text { get; set; }
public bool IsPreferred { get; set; }
}
那里的物品已经预订,所以“下一步”确实意味着什么。
在我的场景中,序列的内容如下所示:
[0] - “a”,false
[1] - “b”,true
[2] - “c”,false
我正试图在IsPreferred == true
之后得到“下一个”元素。所以在上面,我想得到元素2,我想清除其他IsPreferred
值。
所以我想最终得到这个:
[0] - “a”,false
[1] - “b”,false
[2] - “c”,true
基本上将首选项目洗牌。
最好的方法是什么?我唯一能想到的是创建一个新数组,逐个添加它们,跟踪首选数据的索引,然后在上述索引+1处获取元素。
有更好的想法吗?
答案 0 :(得分:5)
我会使用枚举器来迭代集合 - 这就是foreach在幕后所做的事情:
var enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Current.IsPreferred)
{
var oldPreferred = enumerator.Current;
if (enumerator.MoveNext())
{
oldPreferred.IsPreferred = false;
enumerator.Current.IsPreferred = true;
}
break;
}
}
这确实假设你想在找到带有IsPreferred的第一个项目后停止,如果这是最后一个项目,仍然清楚IsPreferred。
编辑:固定边缘情况,其中IsPreferred总是在单个项目的集合上设置为false
答案 1 :(得分:4)
由于ICollection<T>
没有给你一个索引器,我会选择更直接的解决方案而不是依赖LINQ。
假设您希望(1)在条件满足后立即停止,并且(2)仅在下一个项目存在时更改该值,这可以通过以下方式实现:
bool isFound = false;
SomeClass targetItem = null;
foreach (var item in list)
{
if (isFound)
{
item.IsPreferred = true;
targetItem.IsPreferred = false;
break;
}
if (item.IsPreferred)
{
targetItem = item;
isFound = true;
}
}
答案 2 :(得分:3)
我只能想到用LINQ做一个混乱的方式:
var x = collection.SkipWhile(z => !z.IsPreferred);
SomeClass a = x.First();
SomeClass b = x.Skip(1).First();
a.IsPreferred = false;
b.IsPreferred = true;
这当然不包括错误检查,效率不高。
另一种可能性(使用LINQ)将使用Ahmad Mageed的解决方案(如下面的评论所示):
var x = collection.SkipWhile(z => !z.IsPreferred);
SomeClass a = x.FirstOrDefault();
SomeClass b = x.ElementAtOrDefault(1);
if (a != null) a.IsPreferred = false;
if (b != null) b.IsPreferred = true;
答案 3 :(得分:0)
一些想法
答案 4 :(得分:0)
由于您的收藏是订购的,它可以是IList而不是ICollection吗?
然后,您可以创建一个扩展方法,为您提供某些谓词适用的值的索引:
static IEnumerable<int> IndexWhere<T>(this IList<T> list,
Func<T, bool> predicate)
{
for(int i = 0; i < list.Count; i++)
{
if(predicate(list[i])) yield return i;
}
}
假设您只希望一个元素匹配,听起来其余元素就像这样:
var preferredIndex = list.IndexWhere(x=>x.IsPreferred).Single();
list[preferredIndex].IsPreferred = false;
list[preferredIndex + 1].IsPreferred = true;