gpt4 book ai didi

c# - 如何将列表或 IEnumerable 拆分为 N 大小的较小列表?

转载 作者:行者123 更新时间:2023-11-30 19:55:38 24 4
gpt4 key购买 nike

我有很多复选框,目前我想将它们放在 3 列中,每列都有一个 div。

但是我非常反复无常,明天可能想将它们放在 10 或 20 列中,我可能想将其旋转为行或任何其他类型的 div。

3 列的示例:

<div class="column-1">
<input type="checkbox" id="foo-1">Checkbox # 1
<input type="checkbox" id="foo-2">Checkbox # 2
<input type="checkbox" id="foo-3">Checkbox # 3
</div>
<div class="column-2">
<input type="checkbox" id="foo-4">Checkbox # 4
<input type="checkbox" id="foo-5">Checkbox # 5
<input type="checkbox" id="foo-6">Checkbox # 6
</div>
<div class="column-3">
<input type="checkbox" id="foo-7">Checkbox # 7
<input type="checkbox" id="foo-8">Checkbox # 8
<input type="checkbox" id="foo-9">Checkbox # 9
</div>

我首先尝试使用 3 个 while 循环来执行此操作,如下所示:

@{
int i = 0;
IEnumerable<foo> bar = new List<foo>(){foo1,foo2,foo3,foo4,foo5,foo6};
}
<div id="column-1">
while (i < bar.Count() / 3)
{
baz = bar.ElementAt(i);
<input type="checkbox" id="foo-@i" checked='@baz.CheckIt' />@baz.DisplayText
i++;
}
</div>
<div id="column-2">
@while (i < bar.Count() * 2 / 3)
{
baz = bar.ElementAt(i);
<input type="checkbox" id="foo-@i" checked='@baz.CheckIt' />@baz.DisplayText
i++;
}
</div>
<div id="column-3">
@while (i < bar.Count())
{
baz = bar.ElementAt(i);
<input type="checkbox" id="foo-@i" checked='@baz.CheckIt' />@baz.DisplayText
i++;
}
</div>

这很好用,但如果我想使用超过 3 列,就会变得非常难看。老实说已经很丑了。它还不允许轻松更改列数。它也可以更改为 for 循环,每个循环从不同的值(分别为 0、1、2)开始并将 i 递增 3,但这仍然是 3 个循环。

我还尝试使用一些模数运算符在单个循环中执行此操作(伪代码):

i = 0
foreach(checkbox in list)
{
if(i % numberOfColumns == 0)
{
createNewRow()
}
placeCheckBox()
i++
}

在我看来,这更加简洁易读。然而,这会产生大量的行 div,这对我的目的来说效果不佳。还有一个问题是实际上让复选框位于 div 中。上面的两个解决方案可以组合起来创建列而不是行,这看起来更好,但仍然存在与第二个解决方案相同的问题。

我觉得一定有一种更简单更好的方法来做到这一点,而不必对列数进行硬编码,因为没有人愿意编写 20 个基本的 while 循环。

那么有没有一种可扩展且简洁的方法来为分隔为多个 div 的列表中的每个项目生成 html 标签?如果有,那是什么?

最佳答案

这会将 T 的 IEnumerable 拆分为 T 的 IEnumerable 的 IEnumerable。(也许我应该刚刚返回数组。)如果给它 100 并将其分成三组,您将得到 34 组。前 33 组将有 3 个元素,最后一个将有一个。

public static IEnumerable<IEnumerable<T>> SplitIntoSetsOfSpecifiedLength<T>
(this IEnumerable<T> source, int itemsPerSet) // naming is hard
{
var sourceArray = source as T[] ?? source.ToArray();
var result = new List<IEnumerable<T>>();
for (var index = 0; index < sourceArray.Length; index += itemsPerSet)
{
result.Add(sourceArray.Skip(index).Take(itemsPerSet));
}
return result;
}

为了说明,给定一个从 1 到 20 的数字列表的输入,

var splitIntoThreeLists = oneToTwenty.SplitIntoSetsOfSpecifiedLength(7);

将返回三组:

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

单元测试

[TestMethod]
public void splits_20_into_sets_of_seven()
{
var values = Enumerable.Range(1, 20);
var splitValues = values.SplitIntoSetsOfSpecifiedLength(7).ToList();

// three sets
Assert.AreEqual(splitValues.Count(), 3);

// the first set contains the first seven numbers.
Assert.IsTrue(splitValues[0].SequenceEqual(Enumerable.Range(1, 7)));

// the second set contains the next seven numbers
Assert.IsTrue(splitValues[1].SequenceEqual(Enumerable.Range(8, 7)));

// the third set contains the last six
Assert.IsTrue(splitValues[2].SequenceEqual(Enumerable.Range(15, 6)));
}

关于c# - 如何将列表或 IEnumerable 拆分为 N 大小的较小列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36611224/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com