2009-04-22 18 views
13

đầu tiên Tôi muốn lấy phần tử tiếp theo trong danh sách và nếu danh sách ở cuối, tôi muốn phần tử đầu tiên. Vì vậy, tôi chỉ muốn nó vòng tròn nói cách khác.Danh sách <> Nhận phần tử tiếp theo hoặc nhận được

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

Tôi khá hài lòng với giải pháp của riêng tôi trình bày ở trên, cho tôi biết nếu bạn có một tốt hơn một :)

Trả lời

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

việc sử dụng các toán tử MOD % atuomatically chops các chỉ số để một loạt các chỉ số càng tốt.

Toán tử mô đun là lời khen cho toán tử DIV (/) và trả về phần còn lại của một phần của hai số nguyên. Ví dụ nếu bạn chia 9 cho 6 kết quả là 1 với phần còn lại của 3. Toán tử MOD yêu cầu 3.

+0

wow đó là một giải pháp cực kỳ gọn gàng nếu điều đó hoạt động :) cẩn thận để giải thích một chút? –

+0

toán tử mod thực hiện một modulo, chính xác là những gì bạn muốn. Nếu bạn có thể khởi tạo chỉ mục thành 0 thay vì -1, bạn có thể sử dụng: lastAgentIDAarhus = agents [index% (agents.Count - 1)] – configurator

+3

Tôi nghĩ rằng nó nên là 'index% (agents.Count)' –

2

Không phải là một sự khác biệt rất lớn, nhưng ít nhất một số mã ít hơn (ít nhất là trong trình soạn thảo); 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

Như một sự khác biệt một chút về điều này, đây là một phương pháp mở rộng bạn có thể sử dụng để thực hiện bất kỳ IEnumerable ' tròn'

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

vì vậy bạn có thể sử dụng như thế này

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

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

nào sẽ chỉ tiếp tục đi ... :)

+0

nếu có 3 phần tử trong danh sách và nếu tôi sử dụng giá trị chỉ mục là 4 hoặc 5 - để truy cập một mục trong danh sách - tôi có nhận được phần tử đầu tiên và thứ hai của danh sách không? – BKSpurgeon

+0

Tôi không chắc chắn ý bạn là gì. Nếu bạn đang hỏi về việc lập chỉ mục bằng cách sử dụng giải pháp mà tôi phác thảo ở trên thì đây không phải là danh sách mà nó là một IEnumerable và bạn không thể sử dụng một người lập chỉ mục trên IEnumerable, sau đó không, bạn sẽ không. Bạn có thể sử dụng một cái gì đó giống như agents.AsCircularEnumerable(). Skip (10) .irst() thay vào đó. –

11

Hoặc đơn giản là:

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

Ví dụ:

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

Tôi thích Vinicius's idea của việc sử dụng một phương pháp mở rộng. Thật không may, mã anh đăng sẽ ném một ngoại lệ. Này được dựa trên của mình, nhưng nó sẽ không ném một ngoại lệ và nó là rất đơn giản và dễ đọc (IMHO):

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

Nó sẽ trở lại mục đầu tiên trong danh sách nếu các mục đã qua trong không có trong danh sách, kể từ list.IndexOf(item) sẽ trả lại -1 trong trường hợp đó;

+0

Koveras, nơi sẽ tăng ngoại lệ? –

+0

Hãy nhớ rằng list.IndexOf (mục) sẽ trả về -1 nếu không tìm thấy mục nào. –

+0

Đây thực sự là một ý tưởng hay cho phần mở rộng. Tôi sửa đổi nó một chút và thực hiện nó :) – etalon11

0

Bạn nghĩ gì nếu chúng tôi thêm một số kiểm tra để tránh các lỗi phổ biến?

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

chuỗi line = lines [lines.FindIndex (x => x.Contains (item)) + 1];

Các vấn đề liên quan