0

任何人都知道在 c# 中向一系列通用列表添加值的方法吗?

我目前正在建立一个大型List<List<int>>的,整个过程花费的时间太长,我试图避免使用 foreach 循环和嵌套的 foreach 循环以节省一些时间。

假设我在一个通用列表中有 600 行。对于前 200 行中的每一行,我想添加一个“1”。对于接下来的 200 个,我想添加一个“2”。对于接下来的 200 个,我想添加一个“3”。

我现在这样做的方式是,我必须循环 600 次并单独添加每个,而我想做的是循环 3 次并批量添加条目。

我希望的代码是这样的:

List<List<int>> idList = GetFullList(); //list contains 600 rows

int[] newItems = {1, 3, 5};
int count = 0;
int amountToAmend = 200;
foreach (int i in newItems)
{
    //List<int> newID = new List<int>();
    //newID.Add(i);
    (idList.GetRange(count, amountToAmend)).Add(i);    
    count += amountToAmend;
}

显然这不起作用,但希望你能看到我想要的那种东西。在我的应用程序中,我目前需要执行数万个不必要的循环,而如果代码存在,通常少于 10 个循环可以完成这项工作!

更新:我不确定我是否已经很好地解释了这一点,所以只是为了澄清,这里是我在这里寻找的结果

如果我有一个包含 6 行的列表,如下所示:

[6,7,8]
[5,6,7]
[6,4,8]
[2,4,7]
[5,1,7]
[9,3,5]

我知道我想在前 3 行中添加 1,在接下来的 3 行中添加 2,因此它们将变为:

[6,7,8,1]
[5,6,7,1]
[6,4,8,1]
[2,4,7,2]
[5,1,7,2]
[9,3,5,2]

使用 foreach 循环很容易做到这一点,我目前就是这样做的,但由于涉及的数据量很大,我正在寻找减少特定函数所花费时间的方法。我不确定是否存在一种方法,但如果有人知道,那么它将是 Stack Overflow 的好人 :)

4

5 回答 5

0
List<List<int>> idList = GetFullList(); //list contains 600 rows  

var iterator = idList.Begin();

int[] newItems = {1, 3, 5};  
int count = 0;  
int amountToAmend = 200;  
foreach (var item in newItems)
{
   iterator = iterator.AddItem(item);
   iterator = iterator.MoveForward(amountToAmend);
}

public struct NestedListIterator<T>
{
  public NestedListIterator(List<List<T>> lists, int listIndex, int itemIndex)
  {
    this.lists = lists;
    this.ListIndex = listIndex;
    this.ItemIndex = itemIndex;
  }
  public readonly int ListIndex;
  public readonly int ItemIndex;
  public readonly List<List<T>> lists;

  public NestedListIterator<T> AddItem(T item)
  {
    var list = lists.ElementAtOrDefault(ListIndex);
    if (list == null || list.Count < ItemIndex)
      return this;//or throw new Exception(...)
    list.Insert(ItemIndex, item);
    return new NestedListIterator<T>(this.lists, this.ListIndex, this.ItemIndex + 1);
  }
  public NestedListIterator<T> MoveForward(List<List<T>> lists, int index)
  {
    //if (index < 0) throw new Exception(..)
    var listIndex = this.ListIndex;
    var itemIndex = this.ItemIndex + index;
    for (; ; )
    {
      var list = lists.ElementAtOrDefault(ListIndex);
      if (list == null)
        return new NestedListIterator<T>(lists, listIndex, itemIndex);//or throw new Exception(...)
      if (itemIndex <= list.Count)
        return new NestedListIterator<T>(lists, listIndex, itemIndex);

      itemIndex -= list.Count;
      listIndex++;
    }
  }
  public static int Compare(NestedListIterator<T> left, NestedListIterator<T> right)
  {
    var cmp = left.ListIndex.CompareTo(right.ListIndex);
    if (cmp != 0)
      return cmp;
    return left.ItemIndex.CompareTo(right.ItemIndex);
  }
  public static bool operator <(NestedListIterator<T> left, NestedListIterator<T> right)
  {
    return Compare(left, right) < 0;
  }
  public static bool operator >(NestedListIterator<T> left, NestedListIterator<T> right)
  {
    return Compare(left, right) > 0;
  }
}
public static class NestedListIteratorExtension
{
  public static NestedListIterator<T> Begin<T>(this List<List<T>> lists)
  {
    return new NestedListIterator<T>(lists, 0, 0);
  }
  public static NestedListIterator<T> End<T>(this List<List<T>> lists)
  {
    return new NestedListIterator<T>(lists, lists.Count, 0);
  }
}
于 2012-07-25T10:21:56.747 回答
0

你想有amountToAmend时间每个项目newItems
喜欢:
200 次 1
200 次 3
200 次 5

如果是这样,您可以尝试:

int amountToAmend = 200;
List<int> newItems = new List<int>(){ 1, 3, 5 };
<List<int>> idList = new List<List<int>>();
newItems.ForEach(i => idList.Add(new List<int>(Enumerable.Repeat(i, amountToAmend))));
于 2012-07-25T10:02:18.170 回答
0

您可以使用LINQ 中的SkipTake方法。

喜欢idList.Skip(0).Take(200)它会给你列表中的前 200 个项目,然后你可以更新这些项目。

对于更新,您可能会说:

int increment=2;
list.Select(intVal=> intVal+increment).ToList();
于 2012-07-25T09:45:14.170 回答
0

这个怎么样:

foreach (int i in newItems)
{
    foreach (var row in idList.Skip(count).Take(amountToAmend)) 
    {
        row.Add(i);
    }
    count += amountToAmend;
}

或使用 for 循环:

foreach (int i in newItems)
{
    for (int j = 0; j < amountToAmend; j++)
    {
        idList[count + j].Add(i);
    }
    count += amountToAmend;
}
于 2012-07-25T09:47:50.800 回答
0

没有内置函数,尽管您根本无法避免循环(显式或隐式),因为您想向每个列表添加一个新元素。

你可以List.GetRange结合List.ForEach

var newItems = new[] { 1, 2 };
int numPerGroup = (int)(idList.Count / newItems.Length);
for (int i = 0; i < newItems.Length; i++)
    idList.GetRange(i * numPerGroup, numPerGroup)
          .ForEach(l => l.Add(newItems[i]));

请注意,上面不是Linq,即使在 .NET 2.0 中也可以使用


这是我的旧方法,不是您需要的:

您可以使用LinqandEnumerable.GroupBy将平面列表重新分配到嵌套列表中:

int amountToAmend = 200;
// create sample data with 600 integers
List<int> flattened = Enumerable.Range(1, 600).ToList();  
// group these 600 numbers into 3 nested lists with each 200 integers
List<List<int>> unflattened = flattened
    .Select((i, index) => new { i, index })
    .GroupBy(x => x.index / amountToAmend)
    .Select(g => g.Select(x => x.i).ToList())
    .ToList();

这是演示:http: //ideone.com/LlEe2

于 2012-07-25T09:50:28.447 回答