Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in C#, how do I order items in a list where the "largest" values are in the middle of the list

Tags:

c#

list

linq

I have been stumped on this one for a while. I want to take a List and order the list such that the Products with the largest Price end up in the middle of the list. And I also want to do the opposite, i.e. make sure that the items with the largest price end up on the outer boundaries of the list.

Imagine a data structure like this.. 1,2,3,4,5,6,7,8,9,10

In the first scenario I need to get back 1,3,5,7,9,10,8,6,4,2 In the second scenario I need to get back 10,8,6,4,2,1,3,5,7,9

The list may have upwards of 250 items, the numbers will not be evenly distributed, and they will not be sequential, and I wanted to minimize copying. The numbers will be contained in Product objects, and not simple primitive integers.

Is there a simple solution that I am not seeing?

Any thoughts.

So for those of you wondering what I am up to, I am ordering items based on calculated font size. Here is the code that I went with...

The Implementation...

private void Reorder()
{
    var tempList = new LinkedList<DisplayTag>();
    bool even = true;
    foreach (var tag in this) {
        if (even)
            tempList.AddLast(tag);
        else
            tempList.AddFirst(tag);

        even = !even;
    }

    this.Clear();
    this.AddRange(tempList);
}

The Test...

[TestCase(DisplayTagOrder.SmallestToLargest, Result=new[]{10,14,18,22,26,30})]
[TestCase(DisplayTagOrder.LargestToSmallest, Result=new[]{30,26,22,18,14,10})]
[TestCase(DisplayTagOrder.LargestInTheMiddle, Result = new[] { 10, 18, 26, 30, 22, 14 })]
[TestCase(DisplayTagOrder.LargestOnTheEnds, Result = new[] { 30, 22, 14, 10, 18, 26 })]
public int[] CalculateFontSize_Orders_Tags_Appropriately(DisplayTagOrder sortOrder)
{
    list.CloudOrder = sortOrder;
    list.CalculateFontSize();

    var result = (from displayTag in list select displayTag.FontSize).ToArray();
    return result;
}

The Usage...

public void CalculateFontSize()
{
    GetMaximumRange();
    GetMinimunRange();
    CalculateDelta();

    this.ForEach((displayTag) => CalculateFontSize(displayTag));

    OrderByFontSize();
}

private void OrderByFontSize()
{
    switch (CloudOrder) {
        case DisplayTagOrder.SmallestToLargest:
            this.Sort((arg1, arg2) => arg1.FontSize.CompareTo(arg2.FontSize));
            break;
        case DisplayTagOrder.LargestToSmallest:
            this.Sort(new LargestFirstComparer());
            break;
        case DisplayTagOrder.LargestInTheMiddle:
            this.Sort(new LargestFirstComparer());
            Reorder();
            break;
        case DisplayTagOrder.LargestOnTheEnds:
            this.Sort();
            Reorder();
            break;
    }
}
like image 945
CedricB Avatar asked Sep 26 '10 03:09

CedricB


People also ask

What does << mean in C?

<< is the left shift operator. It is shifting the number 1 to the left 0 bits, which is equivalent to the number 1 .

What does %d do in C?

%d is a format specifier, used in C Language. Now a format specifier is indicated by a % (percentage symbol) before the letter describing it. In simple words, a format specifier tells us the type of data to store and print. Now, %d represents the signed decimal integer.

What is && operator in C?

The && (logical AND) operator indicates whether both operands are true. If both operands have nonzero values, the result has the value 1 . Otherwise, the result has the value 0 . The type of the result is int . Both operands must have an arithmetic or pointer type.


1 Answers

The appropriate data structure is a LinkedList because it allows you to efficiently add to either end:

        LinkedList<int> result = new LinkedList<int>();

        int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        Array.Sort(array);

        bool odd = true;

        foreach (var x in array)
        {
            if (odd)
                result.AddLast(x);
            else
                result.AddFirst(x);
            odd = !odd;
        }

        foreach (int item in result)
            Console.Write("{0} ", item);

No extra copying steps, no reversing steps, ... just a small overhead per node for storage.

like image 131
Ian Mercer Avatar answered Sep 28 '22 10:09

Ian Mercer