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 to Objects - ผู้ให้บริการ LINQ รายใดที่คุณใช้งานอยู่จริง

นี่คือตัวอย่าง LINQ to Objects ที่ใช้งานได้:

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 เป็นเท็จอยู่เสมอ .... จึงต้อง
ห้าม

5
ถูกต้องfalse(0) มาก่อนtrue(1) ในลำดับการเรียงลำดับจากน้อยไปหามาก (ค่าเริ่มต้น)
silkfire

ฉันจะจัดกลุ่ม Column1 ตามจำนวนจริงในคอลัมน์ 2 ได้อย่างไร
Oracular Man

2
@OracularMan: ฉันขอแนะนำให้คุณถามคำถามใหม่พร้อมตัวอย่างโดยละเอียด
Jon Skeet

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

119

แค่อยากจะทำสิ่งนี้และดูเหมือนว่าจะมีบางอย่างที่ไม่มีคำสั่งโดยปริยาย ฉันทำสิ่งต่อไปนี้เพื่อให้ชัดเจนยิ่งขึ้น:

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

เพื่อจัดเรียงสิ่งที่เป็นจริงเป็นเท็จ


27
ฉันเป็นแบบนี้มากกว่าที่สร้างขึ้น ส่วนใหญ่เป็นเพราะแม้ว่าจะมีคำสั่งโดยนัยสำหรับ true / false แต่ก็ไม่ชัดเจนสำหรับทุกคนที่ไม่เคยทำมาก่อน ดังนั้นใครบางคนที่ไม่รู้ว่ากำลังมองหาโค้ดในอนาคตอาจคิดว่ามันเรียงลำดับจริงเป็นเท็จเมื่อมันจัดประเภทเท็จเป็นจริง ... อย่างน้อยด้วยวิธีนี้โค้ดจะทำให้ชัดเจนอย่างเจ็บปวดว่าคุณตั้งใจจะเรียงลำดับอย่างไร
Robert Noack

2
ใช่ฉันชอบรหัสนั้น! หากคุณต้องไปที่ msdn หรือ stackoverflow เพื่ออ่านเอกสารเพื่อทำความเข้าใจโค้ดแสดงว่ามันไม่ใช่รหัสที่ดีในความคิดของฉัน
JonnyRaa

2
กลิ่นเหมือนตัวเลขวิเศษสำหรับฉัน ฉันคิดผิดหรือเปล่าที่คิดว่าโปรแกรมเมอร์ทุกคนควรรู้ดีอยู่แล้วว่าบูลีนtrueหมายถึงa single bit set to 1อะไร สำหรับฉันแล้วความจริงtrue > falseนั้นชัดเจนที่สุดเท่าที่จะเป็นไปได้
Mels

4
@ เมลไม่ใช่เลขวิเศษ ค่าที่ชัดเจนใช้สำหรับการเรียงลำดับและการเรียงลำดับเท่านั้น ค่าอาจเป็น 42 และ 69 ประเด็นคือผู้อ่านรหัสรู้ว่าหนึ่งในนั้นมีขนาดเล็กกว่าดังนั้นจึงเป็นอันดับแรก ผู้อ่านโค้ดอาจไม่ทราบว่า OrderBy จะใส่บูลด้วยวิธีใด - จะเป็นจริงก่อนหรือจะเท็จก่อน true > falseไม่เป็นที่รู้จักในระดับสากลในขณะที่1 > 0เป็น
Dan F

9
โปรดทราบว่า.OrderBy(e => e.SomeFlag == true)จะเทียบเท่ากับ.OrderBy(e => e.SomeFlag)ในขณะ.OrderBy(e => e.SomeFlag ? 0 : 1)ที่เทียบเท่ากับ.OrderByDescending(e => e.SomeFlag). สองประเภทแรกเป็นเท็จก่อนจริงและอีกสองประเภทเป็นจริงก่อนเท็จ
EriF89


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; 
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.