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
= 0true
= 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
Calling a Method in Parent Page from User Control
Find Methods That Have Custom Attribute Using Reflection
When Using a Settings.Settings File in .Net, Where Is the Config Actually Stored
How to Format Datetime to Web Utc Format
Entity Framework - Invalid Column Name '*_Id"
How to Auto Resize and Adjust Form Controls with Change in Resolution
String.Isnullorwhitespace in Linq Expression
Mvvm: Binding to Model While Keeping Model in Sync with a Server Version
Differencebetween Casting and Coercing
Read Appsettings JSON Values in .Net Core Test Project
Entity Framework Many to Many Through Containing Object
How to Get a Count of the Total Number of Digits in a Number
How to Create an Xml Document Using Xmldocument