How to order using Linq with missing items?

Usually when using Linq, I usually filtered out empty / null entries using Where or similar. However, I need to order the list according to several criteria and keep all the elements in the list, but in order.

The following only works when .Dimension1.Count > 0for all items in the list

var orderedList = mList.Elements
                       .OrderBy(x => x.Property1)
                       .ThenBy(x => x.Property2)
                       .ThenBy(x => x.Property3.Dimension1[0].Value2)
                       .ToList();

If any of the elements has Dimension1.Count == 0, then I get an error:

'The index was out of range. Must be non-negative and smaller than the size of the collection. ''

The array is not expected to be sized.

Is there a way to make this work when the list contains items that have .Dimension1.Count = 0?

Note that it Dimension1[0].Value2is of type double.

+4
5

- :

var orderedList = mList.Elements.OrderBy(x => x.Property1)
.ThenBy(x => x.Property2)
.ThenBy(x => x.Property3.Dimension1.Count == 0
    ? -1
    : x.Property3.Dimension1[0].Value2)
.ToList();

, Value2 . , , null -1.

, , Count 0.

+5

, , , Entity Framework. , SQL ( ..), .

.ThenBy(x => x.Property3.Dimension1[0].Count > 0 ? x.Property3.Dimension1[0].Value2 : -1)

, Value2 > 0, -1 . , -1 - .

+1

You can simply specify the default value for the second ThenBy.

.ThenBy(x => x.Property3.Dimension1.Any() 
             ? x.Property3.Dimension1[0].Value2 
             : // Some default value for the type of Value2.
               // Go high or low depending on the type to put 
               // them at the top or bottom of the list
        );
+1
source

There is a special LINQ method for this DefaultIfEmpty, which

Returns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty.

var orderedList = mList.Elements
                       .OrderBy(x => x.Property1)
                       .ThenBy(x => x.Property2)
                       .ThenBy(x => x.Property3.Dimension1.DefaultIfEmpty(someDefaultValue).ElementAt(0).Value2)
                       .ToList();
+1
source

if you want to be sure that this will not be a null exception for the Dimensions1 array:

.Then(x => (x.Property3.Dimensions1 ?? new object[0]).Count > 0 ? x.Property3.Dimensions1[0].Value2 : -1)
0
source

Source: https://habr.com/ru/post/1621523/


All Articles