3

を持っていICollection<SomeClass>ます。

public class SomeClass
{
   public string Text { get; set; }
   public bool IsPreferred { get; set; }
}

そこにあるアイテムは予約注文済みなので、「次」には何か意味があります。

私のシナリオでは、シーケンスの内容は次のようになります。

[0] - "a"、偽

[1] - "b"、真

[2] - "c"、偽

その要素の後に「次の」要素を取得しようとしていIsPreferred == trueます。したがって、上記では、要素 2 を取得し、他の値をクリアしたいと考えていIsPreferredます。

だから私はこれで終わりたい:

[0] - "a"、偽

[1] - "b"、偽

[2] - "c"、真

基本的に、好みのアイテムを下にシャッフルします。

それを行う最良の方法は何ですか?私が考えることができる唯一のことは、新しい配列を作成し、それらを1つずつ追加し、優先されるもののインデックスを追跡してから、前述のインデックス+1で要素を取得することです.

より良いアイデアはありますか?

4

5 に答える 5

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 に設定されるエッジ ケースを修正しました

于 2011-12-21T01:00:01.717 に答える
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;
    }
}
于 2011-12-21T01:10:43.173 に答える
0

あなたのコレクションは順序付けられているので、ICollection ではなく IList にすることはできますか?

次に、いくつかの述語が適用される値のインデックスを提供する拡張メソッドを作成できます。

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;
    }
}

1 つの要素だけが一致すると想定すると、残りの要素は次のようになります。

var preferredIndex = list.IndexWhere(x=>x.IsPreferred).Single();
list[preferredIndex].IsPreferred = false;
list[preferredIndex + 1].IsPreferred = true;
于 2011-12-21T00:59:09.207 に答える
0

いくつかのアイデア

  1. コレクションを反復処理できる場合、i+1 を処理する前に i+2 の値を true に設定できないのはなぜですか? i+2 が存在することを確認してください
  2. 別のアイデアは、LinkedListを拡張し、存在する場合は current.next.next = true にすることです。
于 2011-12-21T00:58:45.660 に答える