【问题标题】:Move item to first in array将项目移动到数组中的第一个
【发布时间】:2011-01-18 08:27:24
【问题描述】:

我有一个对象数组

MyObjects[] mos = GetMyObjectsArray();

现在我想将一些 id 为 1085 的元素移到第一个,所以我在 LINQ 中编写了这样的代码,有没有更优雅的方法来做到这一点?

mos.Where(c => c.ID == 1085).Take(1).Concat(mos.Where(c => c.ID != 1085)).ToArray();

注意,我想保存其他项目的定位,所以与第一个项目交换不是解决方案

【问题讨论】:

  • 让您想要的带有id 的项目位于x 位置。如何处理这个“空”项目?折叠还是交换?
  • 您的代码具有其他属性,例如 a) 创建新数组 b) 删除重复的 1085 s。 c) 如果这样的项目不存在,则不投掷。这些必须完全复制吗?
  • 我想保存其他项目的定位,所以与第一个项目交换不是解决方案
  • 为什么不用链表来代替呢?
  • 只是我们在 UI 中有逻辑取决于数组类型,我是后端开发人员,不想更改该逻辑 :) 我知道数组不是您操作的最佳数据结构正在尝试

标签: c# arrays linq


【解决方案1】:

这不是 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 太多了 :)
  • 如果可以void 并抛出异常,返回bool 怎么办?
  • 如果没有找到任何项目,您建议抛出什么异常?参数异常?无效操作异常?
【解决方案2】:

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

首先,定义一个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);

【讨论】:

  • 请注意,在幕后,List 也使用数组。所以这不会比 for 循环解决方案快。更简单。
【解决方案3】:
// 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;

【讨论】:

    猜你喜欢
    • 2013-12-09
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 2023-03-14
    • 2021-08-20
    相关资源
    最近更新 更多