0

想象一下,您有 3 个不同项目的列表。您必须按索引从这些列表之一中返回项目。索引是从 0 到 的数字Count(<all lists items>)

例子:

lists 1: 10 items;
lists 2: 5 item;
lists 3: 1 item;

因此,索引应该在 0 到 15 之间。逐项索引:

0: lists 1, item 0;
1: lists 2, item 0:
2: lists 3, item 0;
3: lists 1, item 1;
4: lists 2, item 1;
5: lists 1, item 2;
6: lists 2, item 2;
7: lists 1, item 3;
8: lists 2, item 3;
9: lists 1, item 4;
10: lists 2, item 4;
11: lists 1, item 5;
12: lists 1, item 6;
13: lists 1, item 7;
14: lists 1, item 8;
15: lists 1, item 9;

(对不起完整的结果。这是为了我自己的理解检查)。

这是最好的方法:

  • 确定使用哪些列表?
  • 列表中的哪个索引用于获取项目?

可能的解决方案:

  1. 将所有列表中的所有项目放入一个大列表中。大列表中的每个项目都应包含:列表索引;列表中的项目(或项目索引);
  2. 当索引到达时,简单地从大列表中返回项目。
4

3 回答 3

1

这是快速解决方案。您可以传递所有列表并获取它们的枚举数。然后迭代枚举器,同时它们可以返回一些结果

public static IEnumerable<T> EnumerateAll<T>(params IEnumerable<T>[] lists)
{
    var enumerators = lists.Select(l => l.GetEnumerator());

    while (enumerators.Any())
    {
        enumerators = enumerators.Where(e => e.MoveNext());

        foreach (var enumerator in enumerators)
            yield return enumerator.Current;           
    }
}

用法:

List<int> list1 = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<int> list2 = new List<int> { 12, 13, 14, 15, 16};
List<int> list3 = new List<int> { 17 };


foreach (int x in EnumerateAll(list1, list2, list3))
    Console.WriteLine(x);

输出

 1 12 17 2 13 3 14 4 15 5 16 6 7 8 9 10

这是更新的解决方案,感谢@Rawling 评论

public static IEnumerable<T> EnumerateAll<T>(params IEnumerable<T>[] lists)
{
    var enumerators = lists.Select(l => l.GetEnumerator()).ToList();

    while (enumerators.Any())
    {
        enumerators.RemoveAll(e => !e.MoveNext());

        foreach (var enumerator in enumerators)
            yield return enumerator.Current;
    }
}

还有一个提示 - 如果您需要按索引引用元素,那么只需调用ToList()or ToArray()

var items = EnumerateAll(list1, list2, list3).ToList();
var item = items[5];
于 2013-06-04T12:18:09.083 回答
1

无需枚举lists,只需检查 是否index小于最小列表计数 (minCount ) 乘以列表长度 ( lists.Length) 如果是这种情况,则要检索的值非常简单,否则从列表中返回索引,不包括具有最小计数 ( minLists) 的列表并相应地调整索引:

(当然,这仅在您有一个ILists (或数组)数组时才有效)

public static T GetByIndex<T>(int index, params IList<T>[] lists){
    var minCount = lists.Min(l => l.Count);
    var minLists = lists.Where(l => l.Count == minCount).ToArray();
    if (index < minCount * lists.Length)
        return lists[index % lists.Length][index / lists.Length];
    else 
        return GetByIndex(index - minCount * minLists.Length, lists.Except(minLists).ToArray());
}

public static void SetByIndex<T>(int index, T val, params IList<T>[] lists){
    var minCount = lists.Min(l => l.Count);
    var minLists = lists.Where(l => l.Count == minCount).ToArray();
    if (index < minCount * lists.Length)
    {
        lists[index % lists.Length][index / lists.Length] = val;
    }
    else 
        SetByIndex(index - minCount * minLists.Length, val, lists.Except(minLists).ToArray());
}
于 2013-06-04T13:17:59.923 回答
0

因此,您有 N 个列表 (L0, L1, .. Ln),其中包含项目数量 (N0, N1 .. Nn),并且您希望在“主索引”K 处从该结构返回元素。

如果 K < N 则从列表编号 K 中返回元素 [0](如果您没有空列表,哈哈)。

如果 K <= N * Min (N0...Nn) 则从 L = K % N 值指定的列表中返回元素 [(K - K % N) / N ](L0 表示 L = 1,L1 表示 L = 2 , L2 代表 L = 0 在你的例子中)。

如果 K > N * Min (N0...Nn),您可能需要将 K 减少短列表的长度,并将每个此类列表的 N 减少 1。

类似的东西,可能你需要通过调试来调整一些值。

于 2013-06-04T11:53:48.357 回答