调整列表大小以适应新的长度

时间:2017-11-06 18:56:46

标签: c# list

假设您将列表定义为:

List<string> list1 = new List<string>{"Cat","Dog","Bird","Badger"};

现在,假设您想编写一个可以获取该列表并更改其长度的通用函数。因此,如果您减去长度以使列表变小,则会截断列表中的项目,或者如果长度较长,则会复制List的内容,然后向其添加新的附加索引。 / p>

更大的长度参数将导致:

List<string> list1 = new List<string>{"Cat","Dog","Bird","Badger","","","","",""};

虽然较小的长度会导致:

List<string> list1 = new List<string>{"Cat","Dog"};

假设不需要进行深度复制,那么如何编写这样的函数?

2 个答案:

答案 0 :(得分:4)

您可以使用AddRangeRemoveRange,这比使用Add和/或RemoveAt循环更好:

public static void PaddedResize<T>(
    List<T> list,
    int size,
    T padding = default(T)
) {
    // Compute difference between actual size and desired size
    var deltaSize = list.Count - size;

    if (deltaSize < 0) {
        // If the list is smaller than target size, fill with `padding`
        list.AddRange(Enumerable.Repeat(padding, -deltaSize));
    } else {
        // If the list is larger than target size, remove end of list
        list.RemoveRange(size, deltaSize);
    }
}

这适用于不可变,引用透明或结构类型,但对于花园种类,它会反复使用相同的元素填充列表,这可能是不理想的。要解决此问题,请使用创建填充的工厂函数:

public static void PaddedResize<T>(
    List<T> list,
    int size,
    Func<T> paddingFactory // Changed parameter to a factory function
) {
    // Compute difference between actual size and desired size
    var deltaSize = list.Count - size;

    if (deltaSize < 0) {
        // If the list is smaller than target size, fill with the result of calling `paddingFactory` for each new item
        list.AddRange(Enumerable.Repeat(0, -deltaSize).Select(_ => paddingFactory()));
    } else {
        // If the list is larger than target size, remove end of list
        list.RemoveRange(size, deltaSize);
    }
}

答案 1 :(得分:-2)

您可能想要创建一些ListUtils类并在那里编写静态泛型函数。如果您想要一个包含所需项目的新列表

static class Listutils 
{
     public static List<T> Shrink<T>(List<T> src, Predicate<T> predicate) 
     {
         if (src == null || src.Count == 0) 
              return null;

         List<T> newList = new List<T>();
         foreach(T item in src) 
         {
            if (predicate(item))
                       newList.Add(item);   
         }

         return newList;
     }
}
........somewhere in your program 
  List<string> list = new List<string>{"Cat","Dog","Bird","Badger","Snake"};

  // select only Cat, Dog and Bird
  List<string> shrinked = ListUtils.Shrink(list, (name) => delegate 
  {
     return (name == "Cat" || name == "Dog" || name == "Bird");
  });