Tôi có một IEnumerable và tôi muốn có một IEnumerable mới chứa mọi phần tử thứ n.Lấy mọi đối tượng thứ 2 trong danh sách
Điều này có thể thực hiện trong LINQ không?
Tôi có một IEnumerable và tôi muốn có một IEnumerable mới chứa mọi phần tử thứ n.Lấy mọi đối tượng thứ 2 trong danh sách
Điều này có thể thực hiện trong LINQ không?
Chỉ cần hình dung nó ra bản thân mình ...
Phương pháp IEnumerable<T>.Where()
có quá tải mà sẽ đưa các chỉ số của phần tử hiện tại - chỉ là những gì bác sĩ đã ra lệnh.
(new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0);
này sẽ quay trở lại
{1, 3, 5}
Cập nhật: Để bao gồm cả trường hợp sử dụng của tôi và đề nghị Dan Tao, chúng ta hãy cũng xác định những yếu tố trở lại đầu tiên nên là:
var firstIdx = 1;
var takeEvery = 2;
var list = new []{1,2,3,4,5};
var newList = list
.Skip(firstIdx)
.Where((elem, idx) => idx % takeEvery == 0);
... sẽ trả lại
{2, 4}
Thực hiện Cristi's suggestion:
public static IEnumerable<T> Sample<T>(this IEnumerable<T> source, int interval)
{
// null check, out of range check go here
return source.Where((value, index) => (index + 1) % interval == 0);
}
Cách sử dụng:
var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evens = upToTen.Sample(2);
var multiplesOfThree = upToTen.Sample(3);
Bạn cũng có thể bỏ qua mảng và sử dụng 'Enumerable.Range (1,10)'. –
@Anthony: Đây chỉ là một ví dụ, nhằm mục đích hiểu ngay lập tức. Tôi biết một số nhà phát triển sẽ phải tra cứu 'Enumerable.Range'. –
Trong khi không phải LINQ bạn cũng có thể tạo ra một phương pháp khuyến nông với yield
.
public static IEnumerable<T> EverySecondObject<T>(this IEnumerable<T> list)
{
using (var enumerator = list.GetEnumerator())
{
while (true)
{
if (!enumerator.MoveNext())
yield break;
if (enumerator.MoveNext())
yield return enumerator.Current;
else
yield break;
}
}
}
Quấn điều đó trong một 'sử dụng'! ('IEnumerable' kế thừa' IDisposable'.) –
@Dan: Bạn có nghĩa là IEnumerator. Sao tôi chưa bao giờ nhận ra điều đó trước đây?
Vâng, tôi có nghĩa là 'IEnumerator'. Rất tiếc! (Vì một lý do nào đó, tôi luôn gõ một khi tôi muốn gõ cái kia. Phải là bộ nhớ cơ.) –
Lần đầu tiên tôi nhìn thấy một cách sử dụng thực sự vững chắc cho chỉ mục trong một thuộc tính tập hợp, bravo, tôi sẽ không nghĩ điều này. –
Bạn có thể xác định phương thức mở rộng sẽ trả về giá trị này.Đây (...) để làm cho điều này rõ ràng hơn trong chính ứng dụng của bạn. – Douglas
Tôi có thể đề xuất sử dụng 'idx + 1' để khớp với mô tả của" mọi phần tử Nth "; ít nhất với tôi, điều này gợi ý rằng phần tử đầu tiên được trả về phải là phần tử thứ N. Vì vậy, mỗi phần tử thứ 2 trong '{1,2,3,4,5}' - thành * me * - có nghĩa là '{2,4}' (mã của bạn trả về '{1,3,5}'). Có lẽ đây là chủ quan, mặc dù. –