如何分配列表中的项目?

时间:2017-06-03 22:29:38

标签: c#

问题:如何按列表数量分配项目?以下是示例:

  • 想象一下,我有8个列表和5个项目。在这种情况下,列表1到5将有1个项目。其余名单仍然是空的。

  • 现在如果我有8个列表和16个项目,每个列表将有2个项目。

  • 如果我有8个列表和11个项目,列表1到3将有两个项目。其余的列表将有1个项目。

var items = new List<object>();
var containers = new List<List<object>>();

int c = -1; // indexer for container.

for(int i = 0; i < items.Count; i++)
{
    // disturbute items to containers

    if (i % (items.Count/containers.Count) == 0) c++; // this is wrong. when to increment?

    containers[c].Add(items[i]);
}

我很确定只有陈述是错误的。令人困惑的是如何处理i

3 个答案:

答案 0 :(得分:2)

试试这个:

    static void Main(string[] args)
    {
        var items = new List<object>() {1, 2, 3, 4, 5, 6};
        var containers = new List<List<object>>() { new List<object>(), new List<object>(),  new List<object>()};

        int c = 0; // indexer for container.
        int containerCount = containers.Count;

        for (int i = 0; i < items.Count; i++, c++)
        {
            c = c % containerCount;
            containers[c].Add(items[i]);
        }
    }

答案 1 :(得分:1)

考虑算法。插入项目时,将其插入列表,然后移动到下一个。到达最后一个列表时,开始插入第一个列表。代码(用记事本编写,因此可能无法编译):

var items = new List<object>();
var containers = new List<List<object>>();

int c = 0;

for (int i = 0; i < items.Count; i++)
{
    c++; // move to next container

    // when reached to the end, insert again to first list
    if (c == containers.Count)
    {
        c = 0;
    }
    containers[c].Add(items[i]);
}

这可以缩短一点:

var items = new List<object>();
var containers = new List<List<object>>();

int c = 0;
foreach (int item in items)
{
    c = (c == containers.Count - 1) ? 0 : c + 1;
    containers[c].Add(item);
}

答案 2 :(得分:1)

如果您想将此行为隔离为可重用且可测试的内容:

public class ListBalancer
{
    public void BalanceItemsBetweenLists<T>(
        IEnumerable<T> input,
        IEnumerable<IList<T>> targets)
    {
        var inputArray = input as T[] ?? input.ToArray();
        var targetArray = targets as IList<T>[] ?? targets.ToArray();
        var currentTargetIndex = 0;
        foreach (var item in inputArray)
        {
            targetArray[currentTargetIndex].Add(item);
            currentTargetIndex++;
            if (currentTargetIndex == targetArray.Length) currentTargetIndex = 0;
        }
    }
}

[TestClass]
public class ListBalancerTests
{
    [TestMethod]
    public void BalancesListsWhenAddingItems()
    {
        var source = Enumerable.Range(1, 11);
        var targets = Enumerable.Range(1, 8).Select(n => new List<int>()).ToArray();
        new ListBalancer().BalanceItemsBetweenLists(source, targets);

        Assert.AreEqual(2, targets[0].Count);
        Assert.AreEqual(2, targets[1].Count);
        Assert.AreEqual(2, targets[2].Count);
        Assert.AreEqual(1, targets[3].Count);
    }
}

这似乎是一些额外的工作。但是你可能发现调试的过程没有做到预期的时候也花了一点时间。可能需要启动控制台应用程序或其他应用程序来测试行为。如果你编写一个带有单元测试的类,你可能仍然需要调试,但它更快,更自包含。您使用一种行为完成了一个类,测试它,然后继续。

我个人发现,一旦我养成习惯,我就可以更快地编写代码并减少错误,因为我使调试过程变得更小更容易。