Reputation: 6175
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
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
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
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