Linq đặt hàng bởi boolean


111

Tôi có một truy vấn linq mà tôi muốn sắp xếp theo f.bar, đây là một chuỗi, nhưng tôi cũng muốn đặt nó bằng f.foo, trước tiên là một trường boolean. Giống như truy vấn dưới đây.

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

Mặc dù điều này biên dịch nó không hoạt động như mong đợi. Nó chỉ ra lệnh bằng f.bar bỏ qua trường boolean.

Tôi biết là tôi đang bối rối, nhưng tôi cần làm gì để có được hành vi này?

Cảm ơn

Câu trả lời:


175

Điều đó sẽ hoạt động tốt - nó phải sắp xếp thứ tự các thực thể có falsegiá trị foo trước, sau đó đến các thực thể có truegiá trị foo.

Điều đó chắc chắn hoạt động trong LINQ to Objects - bạn thực sự đang sử dụng nhà cung cấp LINQ nào?

Dưới đây là một LINQ to Objects dụ mà làm việc:

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
Epic Fail ... chỉ cần nhận ra đó là do lỗi f.foo nghĩa là luôn luôn sai .... vì vậy xấu hổ
mat-McLoughlin

5
Đúng, false(0) đứng trước true(1) theo thứ tự sắp xếp tăng dần (mặc định).
silkfire

Làm cách nào để nhóm Cột 1 theo số true trong Cột 2?
Oracular Man

2
@OracularMan: Tôi khuyên bạn nên đặt một câu hỏi mới với một ví dụ chi tiết.
Jon Skeet

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

119

Chỉ muốn làm điều này và nó có vẻ như một cái gì đó không có mệnh lệnh ngầm. Tôi đã làm như sau để rõ ràng hơn:

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

để sắp xếp một cái gì đó đúng thành sai.


27
Tôi thích điều này hơn là cách xây dựng trong. Chủ yếu là bởi vì ngay cả khi có một thứ tự ngụ ý cho true / false, nó không thực sự rõ ràng đối với bất kỳ ai chưa làm điều đó trước đây. Vì vậy, một người nào đó không biết nhìn vào mã trong tương lai có thể nghĩ rằng nó sắp xếp đúng thành sai, khi thực sự nó sắp xếp sai thành đúng ... ít nhất với giải pháp này, mã làm cho nó rõ ràng một cách đau đớn theo cách bạn định sắp xếp.
Robert Noack,

2
vâng, tôi thích điều đó trong mã! Nếu bạn phải đi vào MSDN hoặc stackoverflow để đọc tài liệu để hiểu mã sau đó nó isnt mã lớn trong quan điểm của tôi
JonnyRaa

2
Nó giống như những con số kỳ diệu đối với tôi. Tôi có sai khi giả định rằng mọi lập trình viên vốn dĩ nên biết rất rõ rằng boolean truecó nghĩa là a single bit set to 1gì không? Đối với tôi, sự thật true > falselà hiển nhiên nhất có thể.
Mels

4
@Mels không phải là con số kỳ diệu. Giá trị rõ ràng chỉ được sử dụng để sắp xếp và sắp xếp. Các giá trị có thể là 42 và 69, điều quan trọng là người đọc mã biết rằng một trong số chúng nhỏ hơn, do đó sẽ là giá trị đầu tiên. Người đọc mã có thể không biết OrderBy sẽ đặt các bools theo cách nào - true sẽ là đầu tiên, hoặc false sẽ là trước. true > falsekhông được biết đến rộng rãi, ngược lại 1 > 0.
Dan F

9
Lưu ý rằng .OrderBy(e => e.SomeFlag == true)sẽ tương đương với .OrderBy(e => e.SomeFlag)trong khi .OrderBy(e => e.SomeFlag ? 0 : 1)tương đương với .OrderByDescending(e => e.SomeFlag). Hai câu đầu tiên sắp xếp false trước true, hai phần còn lại sắp xếp true trước false.
EriF89

0

Vui lòng thử mã sau nếu bạn nhận được thứ tự danh sách đúng.

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

0

Để rõ ràng hơn về thứ tự đang được sử dụng.

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; 
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.