8

次の個別の文字列のリストがあります。

「A」
「B」
「C」

Aの後にアイテムが必要な場合は、Bを取得します。Bの後にCを取得します。Cの後にAを取得します。現在、次のコードがありますが、何らかの理由で、より良い方法があると感じています。これ(多分?)。

private string GetNext(IList<string> items, string curr)
{
    if (String.IsNullOrWhitespace(curr))
        return items[0];

    var index = items.IndexOf(curr);
    if (index == -1)
        return items[0];

    return (index + 1 == items.Count) ? items[0] : items[index + 1];
}

私は間違いなくこれを行うLINQ風の方法にもオープンです:)

4

7 に答える 7

7

あなたが持っている解決策は機能的には正しいですが、そのパフォーマンスには少し不満があります。通常、リスト スタイルの構造を扱う場合GetNext、O(1) 時間で結果が返されると予想されますが、このソリューションは O(N) です。

public sealed class WrappingIterator<T> {
  private IList<T> _list;
  private int _index;
  public WrappingIterator<T>(IList<T> list, int index) {
    _list = list;
    _index = index;
  }
  public T GetNext() {
    _index++;
    if (_index == _list.Count) {
      _index = 0;
    }
    return _list[_index];
  }

  public static WrappingIterator<T> CreateAt(IList<T> list, T value) {
    var index = list.IndexOf(value);
    return new WrappingIterator(list, index);
  }
}

ここでの最初の呼び出しCreateAtは O(N) ですが、その後の呼び出しGetNextは O(1) です。

IList<string> list = ...;
var iterator = WrappingIterator<string>.CreateAt(list, "B");
Console.WriteLine(iterator.GetNext());  // Prints C
Console.WriteLine(iterator.GetNext());  // Prints A
Console.WriteLine(iterator.GetNext());  // Prints B
于 2012-04-23T15:46:09.690 に答える
6

ラインを変えてもいいと思います

return (index + 1 == items.Count) ? items[0] : items[index + 1];

のようなもののために

return items[(index + 1) % items.Count];
于 2012-04-23T15:40:45.753 に答える
1

現在の文字列ではなく現在のインデックスを追跡すると、ある程度の最適化が見られますが、そのためには、アイテムのリストを修正する必要があります。つまり、変更しないでください。

あなたもできますreturn items[(index + 1) % items.Count];

そうでなければ、そのコードは私には問題ないように見えますが、おそらく誰かがもっと賢い解決策を持っています。

于 2012-04-23T15:42:59.797 に答える
1

ここでは、LINQ は適切なツールではありません。

LinkedList<T>ここでは a の方が良いコレクションのように聞こえます。

var linkedItems = new LinkedList<String>(items);
LinkedListNode current = linkedItems.Find("C");
String afterC = current.Next == null ? linkedItems.First.Value : current.Next.Value;

List と比較したLinkedListの長所と短所を次に示します。

于 2012-04-23T15:49:26.623 に答える
1

linq の方法:

var result = (from str in list
              let index = list.IndexOf(curr) + 1
              select list.ElementAtOrDefault(index) ?? list[0]).First();
于 2012-04-23T15:53:02.227 に答える
0

mod演算子を使用して、これを少し単純化し、すべてを1つのステートメントに組み合わせることができます。

return items[((String.IsNullOrWhitespace(curr) 
                ? 0 
                : items.IndexOf(curr)) + 1) % items.Count]

間違いなく短いですが、天気がもっと読みやすいかどうかもわかりません:)

于 2012-04-23T15:42:05.250 に答える
0

最善の解決策は以下のリンクにあると思います。試してみたところ、魅力的に機能しました。

http://www.dotnetperls.com/sort-list

于 2012-04-23T15:52:58.080 に答える