Sorting columns using a list of objects (c#)

September 17th, 2013

Rendering a collection of items in columns could be problematic, at least if you want to sort the items vertically in each column, or you need to use separate surrounding html tags for some reason.

Example: You have a list of letters – a, b, c, d, e, f – and you want to group them like this:
a   c   e
b   d   f

Here is a method I wrote for grouping items into an array of optional size (i.e optional number of columns), which can be used to render any desired columned sorting, vertically or horizontal. This means we don’t have to do some weird clientside hacks using javascript and/or CSS.

The method takes three arguments; a list of any type of objects (either value type or reference type), the number of columns you want to render, and an optional parameter to specify if the sorting should be vertical or horizontal.

Note that the source list should already be in the order you want, this method only takes care of the actual grouping into columns.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Collections.Generic;
 
/// <summary>
/// Groups any list of objects into an array of lists for rendering sorted columns
/// </summary>
/// <typeparam name="T">The type of objects in the list</typeparam>
/// <param name="sourceList">The source list</param>
/// <param name="columns">Number of columns to render. (the size of the array)</param>
/// <param name="horizontal">Optional parameter to specify if the sorting should be vertical or horizontal. Defaults to horizontal sorting.</param>
/// <returns>An array with lists of T sorted as specified</returns>
public List<T>[] SortedColumns<T>(List<T> sourceList, int columns, bool horizontal = true)
{
    if (sourceList == null || sourceList.Count == 0 || columns < 2)
        return null;
 
    var targetList = new List<T>[columns];
    for (int i = 0; i < targetList.Length; i++)
    {
        targetList[i] = new List<T>();
    }
 
    int total = sourceList.Count;
    if (horizontal)
    {
        for (int i = 0; i < total; )
        {
            for (int x = 0; x < targetList.Length; x++)
            {
                if (i < total) { targetList[x].Add(sourceList[i++]); }
            }
        }
    }
    else // vertical
    {
        int columnLimit = (total + (columns - 1)) / columns; // better than Ceiling((double)total / columns)
        for (int i = 0; i < total; )
        {
            for (int x = 0; i < total && x < targetList.Length; x++)
            {
                targetList[x].Add(sourceList[i++]);
                while (i < total && i % columnLimit != 0)
                {
                    targetList[x].Add(sourceList[i++]);
                }
            }
        }
    }
 
    return targetList;
}

Leave a Reply