Boolean'a göre Linq sıralaması


111

Bir dizge olan f.bar'a göre sıralamak istediğim bir linq sorgum var, ama önce boole alanı olan f.foo ile de sıralamak istiyorum. Aşağıdaki sorgu gibi.

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

Bu derlense de beklendiği gibi çalışmıyor. Sadece boole alanını yok sayarak f.bar tarafından sipariş edilir.

Biliyorum aptalca davranıyorum ama bu davranışı almak için ne yapmam gerekiyor?

Teşekkürler

Yanıtlar:


175

Bu iyi çalışmalıdır - falseönce foo değerine sahip varlıkları , sonra truefoo değerine sahip olanları sipariş etmelidir .

Bu kesinlikle LINQ to Objects'te çalışıyor - gerçekte hangi LINQ sağlayıcısını kullanıyorsunuz?

İşte Nesneler Örneğin bir LINQ olduğunu yapar çalışmaları:

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
Destansı başarısız ... f.foo'nun her zaman yanlış olduğu anlamına gelen bir hatadan kaynaklandığını anladım .... çok utandım
mat-mcloughlin

5
Doğru, false(0) trueartan (varsayılan) sıralama düzeninde (1) 'den önce geliyor .
silkfire

Sütun 1'i Sütun 2'deki doğru sayısına göre nasıl gruplandırırım?
Oracular Man

2
@OracularMan: Ayrıntılı bir örnekle yeni bir soru sormanızı öneririm.
Jon Skeet

1
@Sipo: Asdata.OrderBy(d => d.x).ThenBy(d => d.y)
Jon Skeet

119

Sadece bunu yapmak istedim ve örtük düzeni olmayan bir şey gibi görünüyor. Daha açık olmak için şunları yaptım:

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

doğru olan bir şeyi yanlışa sıralamak.


27
Bunu yerleşik yoldan daha çok seviyorum. Temel olarak, doğru / yanlış için zımni bir sıralama olsa bile, bunu daha önce yapmamış olan kimse için gerçekten açık olmadığı için. Bu nedenle, gelecekte koda bakmayı bilmeyen biri, gerçekten yanlışa doğru sıraladığında, yanlışa doğru sıralandığını düşünebilir ... en azından bu çözümle, kod, hangi şekilde sıralamayı planladığınızı acı verici bir şekilde açık hale getirir.
Robert Noack

2
evet bunu kod olarak seviyorum! Kodu anlamak için belgeleri okumak için msdn veya stackoverflow'a gitmeniz gerekiyorsa, o zaman bence bu harika bir kod değil
JonnyRaa

2
Bana sihirli sayılar gibi kokuyor. Her programcının doğası gereği mantıksal bir ifadenin ne trueanlama geldiğini çok iyi bilmesi gerektiğini varsaymakta yanlış mıyım a single bit set to 1? Bana göre, gerçeği true > falseolabildiğince açık.
Mels

4
@Mels sihirli sayılar değildir. Yalnızca sıralama ve sıralama için kullanılan açık değerler. Değerler 42 ve 69 olabilir, önemli olan kodun okuyucusunun bunlardan birinin daha küçük olduğunu bilmesi, dolayısıyla ilk olacağıdır. Kodun okuyucusu muhtemelen bir OrderBy'nin boolleri hangi yöne koyacağını bilmiyor - doğru olacak veya ilk önce yanlış olacak. true > falseevrensel olarak bilinmemektedir, oysa 1 > 0.
Dan F

9
Not .OrderBy(e => e.SomeFlag == true)eşdeğer olacaktır .OrderBy(e => e.SomeFlag), oysa .OrderBy(e => e.SomeFlag ? 0 : 1)eşdeğerdir .OrderByDescending(e => e.SomeFlag). İlk ikisi yanlıştan önce doğru, diğer ikisi yanlıştan önce doğrudur.
EriF89

0

Liste sırasını doğru olarak alırsanız lütfen aşağıdaki kodu deneyin.

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

0

Kullanılan sıra hakkında daha açık olmak için.

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; 
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.