2009-04-22 10 views
13

リスト内の次の要素を取得したいのですが、リストが最後にある場合は最初の要素が必要です。 他の言葉で囲むだけでいいです。List <>次の要素を取得するか最初に取得する

List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch); 
    if (lastAgentIDAarhus != -1) 
    { 
     int index = agents.IndexOf(lastAgentIDAarhus); 
     if (agents.Count > index + 1) 
     { 
      lastAgentIDAarhus = agents[index + 1]; 
     } 
     else 
     { 
      lastAgentIDAarhus = agents[0]; 
     } 
    } 
    else 
    { 
     lastAgentIDAarhus = agents[0]; 
    } 

は、私は上記のように私独自のソリューションとかなり不満です、あなたがより良い1 :)

答えて

20
lastAgentIDAarhus = agents[index == -1 ? 0 : index % agents.Count]; 

がatuomatically可能なインデックスの範囲にインデックスをチョップMODオペレータの使用。

モジュロ演算子は、DIV(/)演算子の補数であり、2つの整数の除算の残りを返します。たとえば、9を6で割った場合、結果は1で残りは3です。MOD演算子は3を求めます。

+0

うわー、それは非常にきちんとした解決策です:) それを少し説明する気に? –

+0

mod演算子はモジュロを行います。これはまさにあなたが望むものです。 lastAgentIDAarhus = agents [index%(agents.Count-1)] – configurator

+3

私はそれが 'index%(agents.Count)'であるべきだと思うでしょう –

2

ない大きな違いがある場合は私に知らせて、しかし、少なくともいくつかの少ないコード(少なくともエディタで); O)

List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch); 
if (lastAgentIDAarhus != -1) 
{ 
    int index = agents.IndexOf(lastAgentIDAarhus); 
    lastAgentIDAarhus = (agents.Count > index + 1 ? agents[index + 1] : agents[0]); 
} 
else 
{ 
    lastAgentIDAarhus = agents[0]; 
} 
4

これとは少し違うので、ここではIEnumerable ' ...

public static IEnumerable<T> AsCircularEnumerable<T>(this IEnumerable<T> enumerable) 
    { 
    var enumerator = enumerable.GetEnumerator(); 
    if(!enumerator.MoveNext()) 
     yield break; 

    while (true) 
    { 
     yield return enumerator.Current; 
     if(!enumerator.MoveNext()) 
     enumerator = enumerable.GetEnumerator(); 
    } 
    } 

ので、あなただけ続けるだろう、この

var agents = new List<int> {1, 2, 3, 4, 123, 234, 345, 546}; 

    foreach(var i in agents.AsCircularEnumerable()) 
    { 
    Console.WriteLine(i); 
    } 

のようなものを使用することができます「円形:)

+0

リストに3つの要素があり、4または5のインデックス値を使用する場合、リストの項目に到達するために、リストの最初と2番目の要素が得られますか? – BKSpurgeon

+0

あなたは何を意味するのか分かりません。上記で概説したソリューションを使用してインデックスを作成することを尋ねる場合は、リストではないためIEnumerableであり、IEnumerableでインデクサーを使用することはできません。あなたはagents.AsCircularEnumerable()のようなものを使うことができます。代わりに.First()をスキップしてください。 –

11

それとも単に:

public static T NextOf<T>(this IList<T> list, T item) 
{ 
    return list[(list.IndexOf(item) + 1) == list.Count ? 0 : (list.IndexOf(item) + 1)]; 
} 

例:

List<string> names = new List<string>(); 

names.Add("jonh"); 
names.Add("mary"); 

string name = String.Empty;  

name = names.NextOf(null); //name == jonh 

name = names.NextOf("jonh"); //name == mary 

name = names.NextOf("mary"); //name == jonh 
3

Iは、拡張メソッドを使用してのVinicius's ideaたい。残念ながら、彼が投稿したコードは例外をスローします。これは彼に基づいていますが、それは例外をスローしないであろうと、(私見)を読むために非常に簡単で簡単です:

public static T Next<T>(this IList<T> list, T item) 
{ 
    var nextIndex = list.IndexOf(item) + 1; 

    if (nextIndex == list.Count) 
    { 
     return list[0]; 
    } 

    return list[nextIndex]; 
} 

に渡されたアイテムが内にない場合には、リストの最初の項目を返します。この場合、list.IndexOf(item)-1を返しますので、リストを参照してください。

+0

Koveras、どこで例外が発生するのですか? –

+0

項目が見つからない場合、list.IndexOf(item)は-1を返します。 –

+0

これは本当に拡張機能のための良いアイデアです。私は少しそれを修正し、それを実装しました:) – etalon11

0

一般的なエラーを避けるためにいくつかのチェックを追加したらどうなると思いますか?

public static class ListExtensions 
{ 
    public static TType Next<TType>(this IList<TType> list, TType item) 
    { 
     if (list == null) return default(TType); 

     var itemIndex = list.IndexOf(item); 
     if (itemIndex < 0) return list.FirstOrDefault(); 

     var nextIndex = itemIndex + 1; 

     return nextIndex >= list.Count 
      ? list.FirstOrDefault() 
      : list[nextIndex]; 
    } 
} 
-4

列ライン=行[lines.FindIndex(X => x.Contains(アイテム))+ 1]。

関連する問題