user1330271
user1330271

Reputation: 2691

Dividing items into columns

I have a dynamic number of items to divide into a maximum of 4 columns, with the proper html format surrounding then, lets say:

string[] s = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; // from 1 to n itens

To format into this html:

<ul>
  <li>
     1
     2
     3
  </li>
  <li>
     4
     5
  </li>
  <li>
     6
     7
  </li>
  <li>
     8
     9
  </li>
</ul>

Edit: my website problem:

If you have words as itens, putting the itens this way will organize the words into alphabetically columns (people read this way), not alphabetically rows. Like:

a d g i
b e h j
c f 

Instead of:

a b c d
e f g h
i j

Upvotes: 3

Views: 1767

Answers (3)

yamen
yamen

Reputation: 15618

Assuming that you want to evenly distribute any remainders, this will do the job:

string[] s = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

// create the 4 buckets with equal distribution
var buckets = Enumerable.Repeat(s.Length / 4, 4).ToArray();

// distribute any remainders evenly starting from the first bucket
var rem = s.Length % 4; 
for (var i = 0; i < rem; i++) buckets[i]++;

var idx = 0;
Console.WriteLine("<ul>");
foreach (var bucket in buckets)
{
    Console.WriteLine("\t<li>");
    foreach (var _ in Enumerable.Range(1, bucket))
    {
        Console.WriteLine("\t\t{0}", s[idx++]);
    }
    Console.WriteLine("\t</li>");
}
Console.WriteLine("</ul>");

For the above code, here is what some edge cases return.

{} = 4 empty items in list

{ "1", "2", "3"} = 1, 2, 3 in the first three items, fourth item empty

{ "1", "2", "3", "4", "5"} = 1, 2 in the first item, 3, 4, 5 in the other items

Upvotes: 5

SPFiredrake
SPFiredrake

Reputation: 3892

Since you want to group by columns instead of rows, just realize that you're ultimately going to have to do SOMETHING with the index. The easiest way to do this is to transform the items into Item/Index pairs and group by those indexes somehow.

s.Select((tr, ti) => new { Index = ti, Item = tr })
 .GroupBy(tr => tr.Index % SOME_MAGIC_NUMBER)

If you want to instead group by rows, change the % operator to a division / and you'll be set. This will now take all your items and group them into the however many items you specify (based on either row or column). To transform them, all you have to do is another select:

.Select(tr => "<li>" + string.Join(" ", tr.Select(tstr => tstr.Item.ToString()).ToArray()) + "</li>")

This will get you a list of all your list items in whatever format you want. If you want to include <br /> between the elements of each <li> then just change the first argument of the string.Join call.

Upvotes: 1

evanmcdonnal
evanmcdonnal

Reputation: 48076

Just loop over the array distributing the array items with a few if statements within it.

int j = 0;

for (int i = 0; i < s.Length; i++)
{
    if (j == 0)
      // put s[i] in column 1 j = j +1
    else if (j == 1)
      // put s[i] in column 2 j = j +1
    else if (j == 2)
      // put s[i] in column 3 j = j +1
    if (j == 3)
      // put s[i] in column 4 set j = 0
}

Upvotes: 1

Related Questions