Linq Order by Boolean

Linq order by boolean

That should work fine - it should order the entities with a false foo value first, then those with a true foo value.

That certainly works in LINQ to Objects - which LINQ provider are you actually using?

Here's a LINQ to Objects example which does work:

using System;
using System.Linq;

public static class Test
{
public static void Main()
{
var data = new[]
{
new { x = false, y = "hello" },
new { x = true, y = "abc" },
new { x = false, y = "def" },
new { x = true, y = "world" }
};

var query = from d in data
orderby d.x, d.y
select d;

foreach (var result in query)
{
Console.WriteLine(result);
}
}

}

C# LINQ Orderby - How does true/false affect orderby?

The OrderBy method will sort items in ascending order by default. Now, given that the numeric representation of a boolean is:

  • false = 0
  • true = 1

false values will naturally come first. If you want to reverse the order just use the descending keyword:

var trueData = (from data in x
orderby numbersToFilterBy.Contains(data.Id) descending, data.Id
select data).ToList();

LINQ: Nested Sorting / Ordering with Boolean Values

var orderedList = list.OrderByDescending(d => d.Value1).
ThenByDescending(d => d.Value1 || d.Value2).
ThenBy(d => d.Value3);

In the 2nd expression I use a combination of Value1 & Value2. If Value1 is true the result will always be true regardless of Value2 and thus 'skip' ordering the results. While if Value1 is false it'll depend solely on Value2.

Linq orderyby boolean

Use the order by descending option and it will reverse the list. See MSDN Soring Data for more examples on sorting.

return from workers in db.Workers
orderby workers.active descending, workers.naam
select workers;

OrderBy boolean of char array

Booleans can be ordered - false comes before true. If you replace the lambda with an s => true or s => false, you give each character the same boolean value to be sorted by, so the original string order will be retained. With this lambda, you assign a random true or false value to each character, and the characters are shuffled.

OrderBy numbers and ThenBy boolean not working for List

Your understanding of what orderby-thenby does is exactly backwards.

You believe, incorrectly, that orderby sorts the list first by integers, and then does a stable re-sort of the list by the Boolean property. That would put all the trues together, sorted by integer, and all the falses together, sorted by integer.

That's not what it does.

The orderby sorts the list by integers, and then the thenby takes all the places where two records sorted to the same integer, and sorts that sub-list by the Boolean property.

This should match your intuition. If I handed you a bunch of cards with numbers and letters and said sort these first by number and then by letter, and I handed you 3A, 2B, 2A, 3B, that the result would be 2A, 2B, 3A, 3B, and not 2A, 3A, 2B, 3B, right?

So you want to reverse your clauses. First orderby the Boolean; that will put all the trues and falses together. Then do a thenby on the integer property, and all the trues will be sorted by integer, and all the falses will be sorted by integer.

That said, orderby in LINQ to Objects is required to be implemented as a stable sort, so if you really want to do it the hard way, you could do an orderby on the integer property and then a second orderby on the Boolean property, and you'd get the right result. But that's wasteful, since it sorts the entire list twice, rather than sorting the entire list once, and then sorting each sublist. Sorting two half lists is usually cheaper than sorting one entire list.

How do I specify LINQ's OrderBy direction as a boolean?

I'd say write your own extension method:

public static IEnumerable<T> Order<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector, bool ascending)
{
if (ascending)
{
return source.OrderBy(selector);
}
else
{
return source.OrderByDescending(selector);
}
}

Then you can just write:

lst = lst.Order( s => s.Letter, isAscending );

As for specifying method name: I hope this doesn't come off as a cop-out answer, but I think you should stick with using a selector function instead of passing in a string. Going the string route doesn't really save you any typing or improve clarity (is "letter" really much faster or clearer than s => s.Letter?) and only makes your code fatter (you'd either need to maintain some sort of mapping from strings to selector functions or write custom parsing logic to convert between them) and possibly more fragile (if you go the latter route, there's a pretty high probability of bugs).

If your intention is to take a string from user input to customize sorting, of course, you have no choice and so feel free to disregard my discouraging remarks!


Edit: Since you are accepting user input, here's what I mean by mapping:

class CustomSorter
{
static Dictionary<string, Func<IMyClass, object>> Selectors;

static CustomSorter()
{
Selectors = new Dictionary<string, Func<IMyClass, object>>
{
{ "letter", new Func<IMyClass, object>(x => x.Letter) },
{ "number", new Func<IMyClass, object>(x => x.Number) }
};
}

public void Sort(IEnumerable<IMyClass> list, string sortField, bool isAscending)
{
Func<IMyClass, object> selector;
if (!Selectors.TryGetValue(sortField, out selector))
{
throw new ArgumentException(string.Format("'{0}' is not a valid sort field.", sortField));
}

// Using extension method defined above.
return list.Order(selector, isAscending);
}
}

The above is clearly not as clever as dynamically generating expressions from strings and invoking them; and that could be considered a strength or a weakness depending on your preference and the team and culture you're a part of. In this particular case, I think I'd vote for the hand-rolled mapping as the dynamic expression route feels over-engineered.

multiple orderby linq query with booleans

Why? If you're using different orderings on different places, just put the LINQ-expressions at these various places?
Seems to me like you're trying to complicate something that's not really that complicated.

data.OrderBy(p => p.Page)
.ThenBy(p => p.Configured)
.ThenBy(...);

GroupBy function to order by boolean

this doesn't give me the expected result, as I would half expect.

Well without knowing what you expect, it's hard to know what's wrong here. It's also not clear whether you've really got that OrderBy call as a statement by itself. If so, that's the problem - LINQ operators don't mutate an existing query; they return a new query. For example, this may be all you need:

mQueryableObject = mQueryableObject.OrderBy(model => model.myBoolean);

This will sort false before true, by the way. If you want it the other way round, just use:

mQueryableObject = mQueryableObject.OrderBy(model => !model.myBoolean);


Related Topics



Leave a reply



Submit