我有一个实现IEnumerable<T>
的列表类
类型T是一个复杂类,其字符串成员作为唯一标识符。但只需将 int 作为元素类型进行解释即可。
我想将多个项目向左移动一步
例如:
原始列表: 0 ,1,2, 3 , 4 ,5 <登记/>
现在所有粗体项(0,3,4)都应该向左移动(尽可能)
结果列表: 0 ,1, 3 , 4 ,2,5 < / p>
有一个很好的算法吗?也许只是LINQ。
编辑:欢迎List<T>
列表的答案。我班有类似的方法。 (感谢TylerOhlsen的暗示。)
编辑2:一个选定的项目不应传递另一个选定的项目。
答案 0 :(得分:3)
这看起来很有效:
public static IEnumerable<T> MoveSelectedLeft<T>(
this IEnumerable<T> source,
IEnumerable<int> indicesToMove /* must be in order! */)
{
using (var itm = indicesToMove.GetEnumerator())
{
bool hasNextToMove = itm.MoveNext();
int nextToMove = hasNextToMove ? itm.Current : -1;
bool canMoveYet = false;
T held = default(T);
int currentIndex = 0;
foreach (T t in source)
{
if (hasNextToMove && nextToMove == currentIndex)
{
hasNextToMove = itm.MoveNext();
nextToMove = hasNextToMove ? itm.Current : -1;
yield return t;
}
else
{
if (!canMoveYet)
{
canMoveYet = true;
}
else
{
yield return held;
}
held = t;
}
currentIndex++;
}
if (canMoveYet)
yield return held;
}
}
称为
foreach (int i in new[] { 0,1,2,3,4,5 }.MoveSelectedLeft(new[] { 0,3,4 }))
{
Console.WriteLine(i);
}
答案 1 :(得分:2)
我没有想出一个使用Linq的好方法,但这是一个简单的循环算法。如果你能想出一个排序功能,那就更好了。或者您可以查看Linq Zip方法。
IList<int> myList = new List<int>(new[] {0, 1, 2, 3, 4, 5});
IList<int> moveLeftList = new List<int>(new[] {0, 1, 3, 4});
//Go through the original list in order and remove
// all items from the move left list until you reach
// the first item that is not going to be moved left.
//Items removed are already as far left as they can be
// so they do not need to be moved left and can therefore
// be safely removed from the list to be moved.
foreach (int item in myList)
{
int index = moveLeftList.IndexOf(item);
if (index >= 0)
moveLeftList.RemoveAt(index);
else
break;
}
foreach (int item in moveLeftList)
{
int index = myList.IndexOf(item);
//Dont move left if it is the first item in the list or it is not in the list
if (index <= 0)
continue;
//Swap with this item with the one to its left
myList.RemoveAt(index);
myList.Insert(index-1, item);
}
答案 2 :(得分:1)
以下是算法的说明。将元素直接存储到`temp变量中的元素组(在本例中为2
)的左侧。
从最左边的元素开始,将元素向左移动1。
将temp
变量放在该组现在的位置右侧。
如果您使用的是链接列表,那可能会更好。您只需将2
从其所在位置移除,然后将其插入该组的右侧即可。
答案 3 :(得分:1)
您应该使用“排序”功能并提供自定义比较器。
看看this example。