Замовлення Linq булевим


111

У мене є запит linq, який я хочу замовити за допомогою f.bar, що є рядком, але я також хочу спочатку замовити його f.foo, що є булевим полем. Як і запит нижче.

(from f in foo
orderby f.foo, f.bar
select f)

Хоча ця компіляція не працює, як очікувалося. Він просто наказує f.bar ігноруючи булеве поле.

Мені здається, що я знаю, але що мені потрібно зробити, щоб отримати таку поведінку?

Дякую

Відповіді:


175

Це повинно спрацювати добре - воно має falseспочатку упорядкувати об'єкти із значенням foo, а потім тими, які мають trueзначення foo.

Це, безумовно, працює в LINQ для об'єктів - який постачальник LINQ ви фактично використовуєте?

Ось LINQ наприклад об'єктів , які роблять роботу:

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);
        }
    }

}

51
Епічний збій ... щойно зрозумів, що це пов’язано з помилкою, що означало, що f.foo завжди був неправдивим .... так збентежено
mat-mcloughlin

5
Правильно, false(0) надходить до true(1) у порядку сортування (за замовчуванням).
шовковий вогонь

Як згрупувати стовпчик1 за кількістю істинних у колонці 2?
Оральна людина

2
@OracularMan: Я пропоную вам задати нове запитання з докладним прикладом.
Джон Скіт

1
@Sipo: Asdata.OrderBy(d => d.x).ThenBy(d => d.y)
Джон Скіт

119

Просто хотів це зробити, і здається, що щось без неявного впорядкування. Я зробив наступне, щоб бути більш чітким:

Something.OrderBy(e=>e.SomeFlag ? 0 : 1) 

сортувати щось істинне до хибного.


27
Мені це подобається більше, ніж побудованому способом. В основному тому, що навіть якщо мається на увазі замовлення на істинне / неправдиве, це насправді не очевидно для тих, хто цього не робив раніше. Тож хтось, хто не знає, дивлячись на код у майбутньому, може подумати, що він сортує правду з помилковим, коли він справді сортує помилковий за істинним ... принаймні за допомогою цього рішення код робить болісно очевидним, який саме спосіб ви маєте намір сортувати.
Роберт Ноак

2
так, мені це подобається в коді! Якщо вам потрібно перейти на msdn або stackoverflow, щоб прочитати документацію, щоб зрозуміти код, то, на мою думку, це не великий код
JonnyRaa

2
Пахне магічними номерами для мене. Я помиляюся, якщо припустити, що кожен програміст повинен дуже добре знати, що trueозначає булевий спосіб a single bit set to 1? Для мене правда true > falseє приблизно такою очевидною, як це може бути.
Мельс,

4
@Мелі не магічні числа. Явні значення, які використовуються лише для сортування та сортування. Значення можуть бути 42 і 69, справа в тому, що читач коду знає, що одне з них менше, тому буде першим. Читач коду, ймовірно, не знає, яким способом OrderBy поставить кулі - правда буде першою, або помилковою буде першою. true > falseне є загальновідомим, тоді як 1 > 0є.
Дан Ф

9
Зауважте, що .OrderBy(e => e.SomeFlag == true)було б еквівалентно .OrderBy(e => e.SomeFlag)тоді .OrderBy(e => e.SomeFlag ? 0 : 1), як еквівалент .OrderByDescending(e => e.SomeFlag). Перші два сорти помилкові перед істинними, інші два сорти - істинні перед хибними.
EriF89

0

Будь ласка, спробуйте наступний код, якщо ви отримаєте порядок у списку за правдивим.

db.member.where(x=>x.id==memberId).OrderBy(x=>!x.IsPrimary?1:0).ToList();

0

Щоб бути більш чітким щодо використовуваного замовлення.

Something.OrderBy(e => e.SomeFlag, new BooleanComparer());

public class BooleanComparer : IComparer<bool>
{
    public int Compare(bool x, bool y)
    {
        int p = x ? 1 : 0;
        int q = y ? 1 : 0;
        return p - q; 
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.