我需要移動IEnumerable中的一個項目>向上移動一個項目。什麼是最簡單的方法來做到這一點?將項目向上移動到IEnumerable
類似的問題在這裏問,但我沒有一個通用的列表只是一個IEnumerable <>:Generic List - moving an item within the list
我需要移動IEnumerable中的一個項目>向上移動一個項目。什麼是最簡單的方法來做到這一點?將項目向上移動到IEnumerable
類似的問題在這裏問,但我沒有一個通用的列表只是一個IEnumerable <>:Generic List - moving an item within the list
作爲@Brian評論這個問題有點不清楚,什麼move an item in an IEnumerable<> up
意味着什麼。
如果您想爲單個項目重新排序IEnumerable,那麼下面的代碼應該是您正在查找的內容。
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> enumerable, int itemIndex)
{
int i = 0;
IEnumerator<T> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
i++;
if (itemIndex.Equals(i))
{
T previous = enumerator.Current;
if (enumerator.MoveNext())
{
yield return enumerator.Current;
}
yield return previous;
break;
}
yield return enumerator.Current;
}
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
這與我正在尋找的東西很接近。謝謝 – Nina 2010-03-13 01:35:31
可以使用ToList()
擴展方法,並使用從您提到的問題的答案。例如
var list = enumerable.ToList();
//do stuff from other answer, and then convert back to enumerable if you want
var reorderedEnumerable = list.AsEnumerable();
或者'enumerable.OrderBy(e => e)'可以做到這一點;-) – Steven 2010-03-12 11:33:45
你不能。 IEnumerable只是迭代通過一些項目,而不是編輯項目列表
我沒有找到任何可以做到你想用IEnumerable <T>。在過去爲特定類型的集合,列表,數組等等開發出類似的東西之後,我覺得是時候更好地研究它了。所以我花了幾分鐘時間寫出一個通用版本,可以應用於任何IEnumerable <T>。
我做了一些基本的測試和參數檢查,但絕不認爲它們是兼容性的。 鑑於聲明,讓我們的代碼:
static class Enumerable {
public static IEnumerable<T> MoveDown<T>(this IEnumerable<T> source, int index) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
if (index == array.Length - 1) {
return source;
}
return Swap<T>(array, index, index + 1);
}
public static IEnumerable<T> MoveDown<T>(this IEnumerable<T> source, T item) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int index = Array.FindIndex(array, i => i.Equals(item));
if (index == -1) {
throw new InvalidOperationException();
}
if (index == array.Length - 1) {
return source;
}
return Swap<T>(array, index, index + 1);
}
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> source, int index) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
if (index == 0) {
return source;
}
return Swap<T>(array, index - 1, index);
}
public static IEnumerable<T> MoveUp<T>(this IEnumerable<T> source, T item) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int index = Array.FindIndex(array, i => i.Equals(item));
if (index == -1) {
throw new InvalidOperationException();
}
if (index == 0) {
return source;
}
return Swap<T>(array, index - 1, index);
}
public static IEnumerable<T> Swap<T>(this IEnumerable<T> source, int firstIndex, int secondIndex) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
return Swap<T>(array, firstIndex, secondIndex);
}
private static IEnumerable<T> Swap<T>(T[] array, int firstIndex, int secondIndex) {
if (firstIndex < 0 || firstIndex >= array.Length) {
throw new ArgumentOutOfRangeException("firstIndex");
}
if (secondIndex < 0 || secondIndex >= array.Length) {
throw new ArgumentOutOfRangeException("secondIndex");
}
T tmp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = tmp;
return array;
}
public static IEnumerable<T> Swap<T>(this IEnumerable<T> source, T firstItem, T secondItem) {
if (source == null) {
throw new ArgumentNullException("source");
}
T[] array = source.ToArray();
int firstIndex = Array.FindIndex(array, i => i.Equals(firstItem));
int secondIndex = Array.FindIndex(array, i => i.Equals(secondItem));
return Swap(array, firstIndex, secondIndex);
}
}
正如你所看到的,上移和下移基本交換操作。通過MoveUp,您可以與前一個元素交換位置,並使用MoveDown交換下一個元素的位置。 當然,這不適用於向上移動第一個元素或向下移動最後一個元素。
運行快速測試與下面的代碼...
class Program {
static void Main(string[] args) {
int[] a = { 0, 2, 1, 3, 4 };
string[] z = { "Zero", "Two", "One", "Three", "Four" };
IEnumerable<int> b = Enumerable.Swap(a, 1, 2);
WriteAll(b);
IEnumerable<int> c = Enumerable.MoveDown(a, 1);
WriteAll(c);
IEnumerable<int> d = Enumerable.MoveUp(a, 2);
WriteAll(d);
IEnumerable<int> f = Enumerable.MoveUp(a, 0);
WriteAll(f);
IEnumerable<int> g = Enumerable.MoveDown(a, 4);
WriteAll(g);
IEnumerable<string> h = Enumerable.Swap(z, "Two", "One");
WriteAll(h);
var i = z.MoveDown("Two");
WriteAll(i);
var j = z.MoveUp("One");
WriteAll(j);
Console.WriteLine("Press any key to continue...");
Console.Read();
}
private static void WriteAll<T>(IEnumerable<T> b) {
foreach (var item in b) {
Console.WriteLine(item);
}
}
...它看起來像一切運作良好。
我希望它至少可以作爲你的起點。
我喜歡這種方法,
/// <summary>
/// Extension methods for <see cref="System.Collections.Generic.List{T}"/>
/// </summary>
public static class ListExtensions
{
public static void MoveForward<T>(this List<T> list, Predicate<T> itemSelector, bool isLastToBeginning)
{
Ensure.ArgumentNotNull(list, "list");
Ensure.ArgumentNotNull(itemSelector, "itemSelector");
var currentIndex = list.FindIndex(itemSelector);
// Copy the current item
var item = list[currentIndex];
bool isLast = list.Count - 1 == currentIndex;
if (isLastToBeginning && isLast)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to the beginning
list.Insert(0, item);
}
else if (!isLast)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item at next index
list.Insert(currentIndex + 1, item);
}
}
public static void MoveBack<T>(this List<T> list, Predicate<T> itemSelector, bool isFirstToEnd)
{
Ensure.ArgumentNotNull(list, "list");
Ensure.ArgumentNotNull(itemSelector, "itemSelector");
var currentIndex = list.FindIndex(itemSelector);
// Copy the current item
var item = list[currentIndex];
bool isFirst = 0 == currentIndex;
if (isFirstToEnd && isFirst)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to the end
list.Add(item);
}
else if (!isFirstToEnd)
{
// Remove the item
list.RemoveAt(currentIndex);
// add the item to previous index
list.Insert(currentIndex - 1, item);
}
}
}
你是什麼意思移到高於其他項目?你想排序的元素? – 2010-03-12 10:27:14