将项目移动到数组的第一个位置

4

我有一个对象数组

MyObjects[] mos = GetMyObjectsArray();

现在我想把 id 为 1085 的元素移到首位,所以我在 LINQ 中编写了以下代码,是否有更优雅的方法来完成这个操作?
mos.Where(c => c.ID == 1085).Take(1).Concat(mos.Where(c => c.ID != 1085)).ToArray();

注意,我希望保存其他项的定位,因此与第一项交换不是解决方案。

你想要的具有 id 的项目位于 x 位置。对于这个“空”项目,应该怎么做?折叠还是交换? - abatishchev
1
您的代码具有其他属性,例如:a)创建新数组;b)删除重复的“1085”项;c)如果不存在这样的项,则不会抛出异常。这些属性必须完全复制吗? - Ani
我想保存其他项目的位置,所以与第一个项目交换位置不是解决方案。 - Arsen Mkrtchyan
1
为什么你不用链表来代替呢? - Brian Rasmussen
只是我们在UI中有依赖于数组类型的逻辑,我是后端开发人员,不想改变那个逻辑 :) 我知道数组并不是您尝试执行的最佳数据结构。 - Arsen Mkrtchyan
3个回答

5

这不是LINQ,但这是我用数组做的方式。

public static bool MoveToFront<T>(this T[] mos, Predicate<T> match)
  {
    if (mos.Length == 0)
    {
      return false;
    }
    var idx = Array.FindIndex(mos, match);
    if (idx == -1)
    {
      return false;
    }
    var tmp = mos[idx];
    Array.Copy(mos, 0, mos, 1, idx);
    mos[0] = tmp;
    return true;
  }

使用方法:

MyObject[] mos = GetArray();
mos.MoveToFront(c => c.ID == 1085);

我可能有点挑剔,但第一行有一个多余的a :) - nik0lai
如果可以使用void和抛出异常,为什么还要返回bool呢? - abatishchev
如果没有找到任何项目,您会建议抛出哪种异常?ArgumentException?InvalidOperationException? - Heini Høgnason

2

数组并不是你正在尝试的操作的最佳数据结构,它可能需要复制大量的项。对于你所做的事情,你应该使用List。

首先,按如下方式定义一个List扩展方法:

static class ListExtensions
{
    public static bool MoveToFront<T>(this List<T> list, Predicate<T> match)
    {
        int idx = list.FindIndex(match);

        if (idx != -1)
        {
            if (idx != 0) // move only if not already in front
            {
                T value = list[idx]; // save matching value
                list.RemoveAt(idx); // remove it from original location
                list.Insert(0, value); // insert in front
            }
            return true;
        }

        return false; // matching value not found
    }
}

然后您可以使用 MoveToFront 扩展方法(从您的示例修改而来):
List<int> mos = GetMyObjectsList();
mos.MoveToFront(i => i == 1085);

3
请注意,在底层,List 也使用数组。因此,这不会比 for 循环的解决方案更快。只是更加简单易懂。 - H H

2
// input array
T[] arr = Get();

// find the item
int index = Array.FindIndex(arr, i => i.ID == 1085);
if (index == -1)
    throw new InvalidOperationException();

// get the item
T item = arr[index];

// place the item to the first position
T[] result = new T[arr.Length];
result[0] = item;

// copy items before the index
if (index > 0)
    Array.Copy(arr, 0, result, 1, index);

// copy items after the index
if (index < arr.Length)
    Array.Copy(arr, index + 1, result, index + 1, arr.Length - index - 1);

return result;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接