Kiểm tra nếu một biến không phải là không và không bằng 0


271

Tôi đang sử dụng đoạn mã sau để kiểm tra xem một biến có phải không và không bằng không

if(discount != nil && discount != 0) 
  ...
end

Có cách nào tốt hơn để làm điều này?


1
Có lẽ bởi vì đó là bản sao chính xác của stackoverflow.com/questions/209495/ săn .
David Nehme

1
Nó nên làm gì nếu discountsai?
Andrew Grimm

1
Tôi nghĩ rằng discount.in? [0, nil]cách sạch hơn có thể
intmarinoreturn0

Câu trả lời:


428
trừ khi giảm giá. | | giảm giá == 0
  # ...
kết thúc

31
Sử dụng 'hoặc' thay vì | |
Orion Edwards

93
@ orion-edwards tại sao?
NARKOZ

39
Sử dụng 'hoặc' là nguy hiểm. 'hoặc' có sự điều hành của nhà điều hành thấp hơn '=', do đó, những điều sau đây có hành vi không mong muốn: a = false hoặc true #a là sai sau tuyên bố này
Tom G

20
@xiy hiện tại hướng dẫn khuyên bạn nên giả vờ hoặc và không tồn tại (|| là hay & & và?)
user3125280

67
"Hướng dẫn phong cách Ruby" hiện tại The and and or keywords are banned. It's just not worth it. Always use && and || instead.. Và nó đúng, vì lý do David và Tom.
Andre Figueiredo

40
class Object
  def nil_zero?
    self.nil? || self == 0
  end
end

# which lets you do
nil.nil_zero? # returns true
0.nil_zero?   # returns true
1.nil_zero?   # returns false
"a".nil_zero? # returns false

unless discount.nil_zero?
  # do stuff...
end

Cẩn thận với những từ chối thông thường ... sức mạnh / trách nhiệm lớn, việc vá khỉ dẫn đến mặt tối, v.v.


28

ok, sau 5 năm trôi qua ....

if discount.try :nonzero?
  ...
end

Điều quan trọng cần lưu ý trylà được xác định trong đá quý ActiveSupport, vì vậy nó không có sẵn trong ruby ​​đơn giản.


7
Lưu ý rằng đây là một câu trả lời dành riêng cho đường ray . Vanilla ruby ​​không có tryphương pháp.
Tom Lord

Chính xác. Mặc dù nó giống như ActiveSupport cụ thể, đây là một phụ thuộc nhẹ hơn và được sử dụng rộng rãi hơn so với đường ray đầy đủ. Dù sao bây giờ phản hồi của @ ndn là đúng.
viết lại

Được chỉnh sửa để sử dụng điều hướng an toàn
viết lại vào

1
Câu trả lời bây giờ trùng lặp stackoverflow.com/a 432819818/1954610 ... Tôi nghĩ rằng có giá trị khi để nó tryhiển thị tùy chọn thay thế (đây là lý do tại sao nó được nâng cấp ở vị trí đầu tiên!), Miễn là nó rõ ràng người đọc ActiveSupportkhông phải là vani ruby.
Tom Lord

Điểm lấy, trả lời lăn lại.
viết lại

27
trừ khi [không, 0]. bao gồm? (giảm giá) 
  # ...
kết thúc

13
Xinh đẹp? Đúng. Có đọc được không? Không hẳn vậy.
El Ninja Trepador

1
Tôi thấy điều này hoàn toàn dễ đọc, và tôi thích nó hơn một lớp mới. Làm tốt.
colincr

Cách tiếp cận rubyist nhất của việc xử lý hai điều kiện.
Yugendran

23

Từ Ruby 2.3.0 trở đi, bạn có thể kết hợp toán tử điều hướng an toàn ( &.) với Numeric#nonzero?. &.trả về nilnếu thể hiện là nilnonzero?- nếu số đó là 0:

if discount&.nonzero?
  # ...
end

Hoặc hậu tố:

do_something if discount&.nonzero?

"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String.... Điều này không an toàn để sử dụng trên các đối tượng tùy ý.
Tom Lord

2
@TomLord, như đã nêu trong bình luận trước, điều này không nhằm làm việc với các đối tượng tùy ý. Thay vào đó, nó liên quan đến trường hợp khi bạn có một cái gì đó bạn biết nên là một con số, nhưng cũng có thể là nil.
ndnenkov

Tôi sẽ làm cho sự thật đó rõ ràng trong câu trả lời, thay vì ai đó đọc lướt qua điều này và không phát hiện ra sự từ chối trong các bình luận.
Tom Lord

@TomLord, nó được ghi trong câu trả lời " nonzero?- nếu số đó0" . Ngoài ra, cần phải kiểm tra xem một đối tượng hoàn toàn tùy ý có 0phát sinh cực kỳ hiếm khi so với điều đó để kiểm tra một số có thể có hoặc không nil. Do đó nó gần như ngụ ý. Ngay cả khi ai đó bằng cách nào đó đưa ra giả định ngược lại, họ sẽ ngay lập tức hiểu những gì đang xảy ra khi họ cố gắng thực hiện nó.
ndnenkov


15

Bạn có thể làm điều này:

if (!discount.nil? && !discount.zero?)

Thứ tự ở đây rất quan trọng, bởi vì nếu discountnilthì nó sẽ không có zero?phương thức. discount.zero?Tuy nhiên, đánh giá ngắn mạch của Ruby sẽ ngăn nó cố gắng đánh giá , tuy nhiên, nếu discountnil.


11

Bạn có thể chuyển đổi hàng trống của mình thành giá trị nguyên và kiểm tra số không?.

"".to_i.zero? => true
nil.to_i.zero? => true

cẩn thận: 0,1.to_i == 0
Simon B.

3
if discount and discount != 0
  ..
end

cập nhật, nó sẽ falsechodiscount = false


2

Bạn có thể tận dụng phương thức NilClassđược cung cấp #to_i, phương thức này sẽ trả về 0 cho nilcác giá trị:

unless discount.to_i.zero?
  # Code here
end

Nếu discountcó thể là số phân số, bạn có thể sử dụng #to_fthay thế, để ngăn số được làm tròn thành số không.


Đây có phải là giống như câu trả lời của @ oivoodo không?
Cary Swoveland

Không làm việc cho các đối tượng tùy ý . "".to_i == "foo".to_i == "0".to_i == 0. Phương pháp của bạn sẽ làm cho tất cả các loại ép buộc ngoài ý muốn. Nó cũng sẽ thất bại với một NoMethodErrornếu discountkhông đáp ứng to_i.
Tom Lord

2
def is_nil_and_zero(data)
     data.blank? || data == 0 
end  

Nếu chúng ta vượt qua "" nó sẽ trả về false trong khi để trống? trả về đúng Tương tự là trường hợp khi dữ liệu = sai trống? trả về true cho nil, false, trống hoặc chuỗi khoảng trắng. Vì vậy, tốt hơn là sử dụng trống? phương pháp để tránh chuỗi rỗng là tốt.


1
blank?là một phương pháp dành riêng cho đường ray, và không có sẵn trong vani ruby.
Tom Lord

Bạn nói đúng!! Tôi nghĩ rằng điều này có liên quan đến thẻ "ror" nên được đăng ở đây. Lỗi của tôi. Điều này sẽ không làm việc trong vani ruby.
Saroj

1

Khi xử lý một bản ghi cơ sở dữ liệu , tôi muốn khởi tạo tất cả các giá trị trống bằng 0, sử dụng trình trợ giúp di chuyển:

add_column :products, :price, :integer, default: 0

0

Bạn có thể khởi tạo giảm giá về 0 miễn là mã của bạn được đảm bảo không thử và sử dụng nó trước khi được khởi tạo. Điều đó sẽ loại bỏ một kiểm tra mà tôi cho rằng, tôi không thể nghĩ gì khác.



0

Tôi thích sử dụng một cách tiếp cận sạch hơn:

val.to_i.zero?

val.to_isẽ trả về a 0nếu val là a nil,

sau đó, tất cả những gì chúng ta cần làm là kiểm tra xem giá trị cuối cùng có bằng không hay không .


-1

Giải pháp thay thế là sử dụng các sàng lọc, như vậy:

module Nothingness
  refine Numeric do
    alias_method :nothing?, :zero?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

if discount.nothing?
  # do something
end

-7

Tôi tin rằng sau đây là đủ tốt cho mã ruby. Tôi không nghĩ rằng tôi có thể viết một bài kiểm tra đơn vị cho thấy bất kỳ sự khác biệt giữa điều này và bản gốc.

if discount != 0
end

8
Nó sẽ đánh giá truenếu giảm giá nil.
Andrew Grimm
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.