Gimly
Gimly

Reputation: 6175

C# Reordering array by index even ascending odd descending

I need to reorder an array by skipping one element each time, first taking the evenly indexed elements ascending, and then taking the oddly indexed elements in descending order.

For example, say I have an array of double that is ordered like this:

[0, 0.3, 0.7, 1.1, 1.5, 1.9, 2.3, 2.7, 3.1, 3.5, 3.9]

I would like to have it ordered like this:

[0, 0.7, 1.5, 2.3, 3.1, 3.9, 3.5, 2.7, 1.9, 1.1, 0.3]

As you can see, I'm not interested in ordering by the values, but only the index of the elements. I can't find an overload of Array.Sort or IEnumerable<>.OrderBy that gives the index, so I can't seem to use that.

I feel a bit ashamed to ask what seems like such a simple question, but I can't figure out how to do that elegantly. I can of course do it with a foreach loop and playing with the indexes, but I'm "translating" some Matlab code and this particular part is made with this elegant (albeit complex to understand if you're not used to that kind of things) one liner:

y = y([1:2:n 2 * floor(n / 2):-2:2],:); % n being the number of elements in the array y

Upvotes: 1

Views: 480

Answers (3)

Perfect28
Perfect28

Reputation: 11327

As elegance is subjective, let me suggest you this :

double [] elements = {0, 0.3, 0.7, 1.1, 1.5, 1.9, 2.3, 2.7, 3.1, 3.5, 3.9};

double [] result = elements
             .Select((value, index) => new {Index = index, Value = value})
             .OrderBy(a => a.Index % 2)
             .ThenBy(a => (a.Index % 2 == 0 ? 1 : -1) * a.Value)
             .Select(a => a.Value).ToArray(); 

Upvotes: 0

ChrisF
ChrisF

Reputation: 137198

This code will take every other element of the array:

var firstHalf = a.Where((value, index) => index % 2 == 0);

A simple modification will get the other set:

var secondHalf = a.Where((value, index) => index % 2 == 1).Reverse();

Then you can combine the two:

var result = firstHalf.Concat(secondHalf);

Upvotes: 6

Lewis Taylor
Lewis Taylor

Reputation: 728

You could get all the odd and even indexes using linq like so:

double[] ar = new double[]{0, 0.3, 0.7, 1.1, 1.5, 1.9, 2.3, 2.7, 3.1, 3.5, 3.9};
var odds = ar.Where((val, index) => index % 2 != 0);
var evens = ar.Where((val, index) => index % 2 == 0);

then reverse the odds and combine the two

Upvotes: 1

Related Questions