views:

1069

answers:

5

Hi. I use linq To Objects instructions on an ordered array. Which operations shouldn't I do to be sure the order of the array is not changed?

+2  A: 

Are you actually talking about SQL, or about arrays? To put it another way, are you using LINQ to SQL or LINQ to Objects?

The LINQ to Objects operators don't actually change their original data source - they build sequences which are effectively backed by the data source. The only operations which change the ordering are OrderBy/OrderByDescending/ThenBy/ThenByDescending - and even then, those are stable for equally ordered elements. Of course, many operations will filter out some elements, but the elements which are returned will be in the same order.

If you convert to a different data structure, e.g. with ToLookup or ToDictionary, I don't believe order is preserved at that point - but that's somewhat different anyway. (The order of values mapping to the same key is preserved for lookups though, I believe.)

Jon Skeet
A: 

If you are working on an array, it sounds like you are using LINQ-to-Objects, not SQL; can you confirm? Most LINQ operations don't re-order anything (the output will be in the same order as the input) - so don't apply another sort (OrderBy[Descending]/ThenBy[Descending]).

[edit: as Jon put more clearly; LINQ generally creates a new sequence, leaving the original data alone]

Note that pushing the data into a Dictionary<,> (ToDictionary) will scramble the data, as dictionary does not respect any particular sort order.

But most common things (Select, Where, Skip, Take) should be fine.

Marc Gravell
A: 

Thanks a lot for the answer. In fact I use LINQ to Objects on arrays of double which stand for timeSeries.

I had problems with OrderBy which gave back an enumerable sequence in a different order than the order I thought it would be, so I was scared other LINQ commands could have same behaviour for speed improvement in the LINQ implementation. If it is only with OrderBy and ThenBy, then it's fine.

Thank you

Matthieu Durut
How was OrderBy behaving oddly for you?
Jon Skeet
Apologize, in fact it was with GroupBy : people I work with had one day some surprise with GroupBy where the order in which the groups were made was not the natural one, but I don't have more information about it.
Matthieu Durut
GroupBy still preserves order in a well-defined way: the groups are effectively ordered by "first element producing the key for that group". In other words, if you imagine a list of current groups, each time a new key is seen, the new group is added to the end of the list.
Jon Skeet
What do you call the "natural" order? The order that unique keys are first found, or the keys sorted in ascending order? I'd expect the first...
Marc Gravell
The order unique keys are first found.The way GroupBy works, as you describe it, seem quite natural.I never experienced the problem myself so I cannot tell you more... But as far as I'm concerned, I just use skip select where take average so the order will be safe for sure. Thanks you once more
Matthieu Durut
It would be better if you edited your original question (at the top) with this info. That would improve the quality of the answers you receive. This is not a discussion thread. This item you posted (that I am commenting on) is an *answer*.
Jason Jackson
A: 

Any 'group by' or 'order by' will possibly change the order.

leppie
+19  A: 

I examined the methods of System.Linq.Enumerable, discarding any that returned non-IEnumerable results. I checked the remarks of each to determine how the order of the result would differ from order of the source.

Preserves Order Absolutely. You can map a source element by index to a result element

  • AsEnumerable
  • Cast
  • Concat
  • Select
  • ToArray
  • ToList

Preserves Order. Elements are filtered, but not re-ordered.

  • Except
  • Intersect
  • OfType
  • Skip
  • SkipWhile
  • Take
  • TakeWhile
  • Where

Destroys Order - we don't know what order to expect results in.

  • Distinct
  • ToDictionary
  • ToLookup

Redefines Order Explicitly - use these to change the order of the result

  • OrderBy
  • OrderByDescending
  • Reverse
  • ThenBy
  • ThenByDescending

Redefines Order as side-effect

  • GroupBy - The IGrouping objects are yielded in an order based on the order of the elements in source that produced the first key of each IGrouping. Elements in a grouping are yielded in the order they appear in source.
  • GroupJoin - GroupJoin preserves the order of the elements of outer, and for each element of outer, the order of the matching elements from inner.
  • Join - preserves the order of the elements of outer, and for each of these elements, the order of the matching elements of inner.
  • SelectMany - for each element of source, selector is invoked and a sequence of values is returned.
  • Union - When the object returned by this method is enumerated, Union enumerates first and second in that order and yields each element that has not already been yielded.
David B
Actually, I think Distinct preserves original (first found) order - so {1,2,1,3,1,3,4,1,5} would be {1,2,3,4,5}
Marc Gravell
http://msdn.microsoft.com/en-us/library/bb348436.aspxThe Distinct<(Of <(TSource>)>)(IEnumerable<(Of <(TSource>)>)) method returns an unordered sequence that contains no duplicate values.
David B
Marc: what you say could be true, but it would be a bad idea to rely on that behavior.
David B
This is a fantastic list, thank you for doing the research on this!
ckittel