C#算法重构将数组分成3部分?

Hca*_*tek 5 c# linq algorithm loops

我有一个IEnumerable,我想使用以下业务逻辑将数据分成3列.如果3个或更少的项目,每列1个项目,我希望将总项目除以3的任何其他东西分割前两个列之间的剩余物(1或2个项目).现在这非常难看,但它确实起了作用.我正在寻找更好地利用linq或可能消除switch语句的技巧.任何改进代码的建议或提示都表示赞赏.

var numItems = items.Count;

            IEnumerable<JToken> col1Items,
                                col2Items, 
                                col3Items;


            if(numItems <=3)
            {
                col1Items = items.Take(1);
                col2Items = items.Skip(1).Take(1);
                col3Items = items.Skip(2).Take(1);

            } else {

                int remainder = numItems % 3,
                    take = numItems / 3,
                    col1Take, 
                    col2Take, 
                    col3Take;

                switch(remainder)
                {
                    case 1:
                        col1Take = take + 1;
                        col2Take = take;
                        col3Take = take;
                        break;
                    case 2:
                        col1Take = take + 1;
                        col2Take = take + 1;
                        col3Take = take;
                        break;
                    default:
                        col1Take = take;
                        col2Take = take;
                        col3Take = take;
                        break;

                }

                col1Items = items.Take(col1Take);
                col2Items = items.Skip(col1Take).Take(col2Take);
                col3Items = items.Skip(col1Take + col2Take).Take(col3Take);
Run Code Online (Sandbox Code Playgroud)

最终我在mvc Razor视图中使用它们

<div class="widgetColumn">
                @Html.DisplayFor(m => col1Items, "MenuColumn")                       
            </div> 

            <div class="widgetColumn">
                @Html.DisplayFor(m => col2Items, "MenuColumn")                       
            </div> 

            <div class="widgetColumn">
                @Html.DisplayFor(m => col3Items, "MenuColumn")                       
            </div>  
Run Code Online (Sandbox Code Playgroud)

在我的第一次尝试中,我想摆脱colNItems和colNTake变量,但我无法弄清楚正确的算法,使其工作相同.

for (int i = 1; i <= 3; i++ )
            {
                IEnumerable<JToken> widgets = new List<JToken>();
                var col = i;
                switch(col)
                {
                    case 1:
                       break;
                    case 2:
                        break;
                    case 3:
                        break;
                }
            }
Run Code Online (Sandbox Code Playgroud)

Bri*_*all 6

列是固定宽度的吗?如果是这样,那么就没有必要对你的收藏做任何特别的事情了.只需依靠浏览器为您完成.有一个外部容器,其总宽度为3列,然后只为每个项目填充一个div(并向左浮动).将内部容器设置为宽度恰好为外部容器的1/3.

这是一个快速的小提琴

这是对风格的快速暗示

div#outer{
    width:300px;    
}

div#outer > div{
    width:100px;
    float:left;    
}
Run Code Online (Sandbox Code Playgroud)


rsl*_*ite 1

你可以概括一下:

int cols = 3;
IEnumerable<JToken> colItems[3]; // you can make this dynamic of course

int rem = numItems % cols;
int len = numItems / cols;

for (int col=0; col<cols; col++){
    int colTake = len;
    if (col < rem) colTake++;
    colItems[col] = items.Skip(col*len).Take(colTake);
}
Run Code Online (Sandbox Code Playgroud)

尚未测试,但这应该适用于任意数量的列。

另外,每当您需要变量 col1、col2、col3 时,请考虑 col[0]、col[1]、col[2]。