2013-05-16 32 views
8

Tôi có một đoạn mã trong Ruby mà đi như sau:thể một "if (a == b || c == b)" tuyên bố được thực hiện ngắn hơn trong Ruby

def check 
    if a == b || c == b 
    # execute some code 
    # b = the same variable 
    end 
end 

này có thể được viết như

def check 
    if a || c == b 
    # this doesn't do the trick 
    end 
    if (a || c) == b 
    # this also doesn't do the magic as I thought it would 
    end 
end 

Hoặc theo cách mà tôi không cần nhập b hai lần. Đây là sự lười biếng và tôi muốn biết.

+0

điều gì sai với '(a || c) == b'? Đó là imo ngược, như tôi đề nghị thử 'b == (a || c) '(theo sau các quy ước đại số boolean tốt hơn). – acolyte

+0

@acolyte Trường hợp nào khi 'a = 1'' c = 0' 'b = 0'? –

+0

@RyanAmos rồi b == c, do đó đánh giá có điều kiện là đúng. trừ khi ruby ​​có một số ý nghĩa thay thế cho '||'. Tôi đã giả định rằng đứng cho hợp lý HOẶC. – acolyte

Trả lời

20
if [a, c].include? b 
    # code 
end 

này được, tuy nhiên, chậm hơn so với mã bạn muốn tránh đáng kể - ít nhất là chừng nào a, bc là dữ liệu cơ bản. Số đo của tôi cho thấy một yếu tố của 3. Điều này có thể là do việc tạo đối tượng Array bổ sung. Vì vậy, bạn có thể phải cân nhắc DRY chống lại hiệu suất ở đây. Bình thường, nó không phải là vấn đề, bởi vì cả hai biến thể không mất nhiều thời gian.

+2

Đẹp, nhưng nó thực sự dài hơn 1 ký tự, tôi đoán nó phụ thuộc vào tên biến. Nó có tác động đến hiệu suất không? – zakinster

+2

@zakinster: :-) Số ký tự không phải là mục tiêu của câu hỏi. Vấn đề là nhiều hơn để tránh sự lặp lại. Thay vì 'b', có thể có thứ phức tạp hơn. Hoặc, khi trao đổi 'b' bằng biến khác, bạn không phải thay đổi nó ở hai nơi (ít lỗi hơn). –

+1

Số lượng ký tự hoặc khoảng trắng, chỉ có hiệu ứng cận biên trong khi phiên dịch đầu tiên truyền qua mã. Sau khi tính số ký tự đó không phải là vấn đề. Thay đổi thuật toán và phương pháp được sử dụng có ảnh hưởng lớn hơn đến tốc độ thực thi. –

0

câu trả lời của @ undur_gongor là hoàn toàn chính xác. Chỉ cần thêm tuy nhiên, nếu bạn đang làm việc với mảng, ví dụ:

a = [1,2,3] 
c = [4,5,6] 

b = [5,6] 

if [a, c].include? b 
    # won't work if your desired result is true 
end 

Bạn sẽ phải làm điều gì đó như:

if [a,c].any?{ |i| (i&b).length == b.length } 
    # assuming that you're always working with arrays 
end 

# otherwise .. 
if [a,c].any?{ |i| ([i].flatten&[b].flatten).length == [b].flatten.length } 
    # this'll handle objects other than arrays too. 
end 
3

Bạn thực sự nên biết tại sao điều này không làm việc:

(a || c) == b 

Điều này có vẻ như một bản dịch của câu "a hoặc c bằng b", có ý nghĩa bằng tiếng Anh.

Trong hầu hết các ngôn ngữ lập trình, (a || c) là một biểu thức có kết quả được đánh giá sẽ được so sánh với b. Bản dịch sang tiếng Anh là "Kết quả của phép toán" a hoặc c "bằng b".

6

Trong khi không phải là một tương đương chính xác của a == b || a == c, case tuyên bố cung cấp cú pháp cho việc này:

case a 
when b, c then puts "It's b or c." 
else puts "It's something else." 
end 

Hãy opent Ruby sách giáo khoa gần nhất và đọc về cách case công trình tuyên bố. Spoiler: Nó hoạt động bằng cách gọi #=== phương pháp trên các đối tượng so sánh:

a = 42 
b, c = Object.new, Object.new 
def b.=== other; puts "b#=== called" end 
def c.=== other; puts "c#=== called" end 

Bây giờ chạy

case a 
when b, c then true 
else false end 

này cung cấp cho bạn rất nhiều tính linh hoạt. Nó đòi hỏi công việc ở văn phòng sau, nhưng sau khi bạn làm điều đó, trông giống như ma thuật ở văn phòng phía trước.

+0

điều này dường như là cách rubyonic nhất đối với tôi. sạch sẽ và dễ đọc! (cũng, +1 cho 42) – caesarsol

+0

Lưu ý rằng điều này có thể được khái quát hóa và thực hiện một cách hoành tráng: 'arr = [b, c]; trường hợp a; khi * arr sau đó ... '. –

-1

Điều này thì sao? nếu [a, c] .index (b)! = Nil; đặt "b = a hoặc b = c"; kết thúc

-1

Acolyte chỉ ra rằng bạn có thể sử dụng b == (a||c), bạn chỉ có nó ngược, nhưng chỉ hoạt động cho giá trị bên trái, vì (a || c) luôn luôn là một giả định không phải là falsey.

Tùy chọn khác là sử dụng toán tử bậc ba.

a==b ? true : b==c 

Tôi không chắc chắn về sự khác biệt tốc độ trích dẫn wrt phương pháp mảng, nhưng tôi sẽ nghĩ rằng đây có thể là nhanh hơn vì nó làm một hoặc hai so sánh và không cần để đối phó với mảng. Ngoài ra, tôi giả sử nó chính xác giống như (a == b || b == c), nhưng đó là một cách thay thế phong cách.

Các vấn đề liên quan