Risposte:
any?
non è lo stesso not empty?
di alcuni casi.
>> [nil, 1].any?
=> true
>> [nil, nil].any?
=> false
Dalla documentazione:
Se il blocco non viene fornito, Ruby aggiunge un blocco implicito di {| obj | obj} (ovvero qualsiasi? restituirà vero se almeno uno dei membri della raccolta non è falso o nullo).
present?
metodo.
#present?
è solo Rails. In puro rubino otterrai NoMethodError: undefined method 'present?' for Array
.
require 'activesupport'
.
true
o se è vuoto.Il metodo empty?
viene dalla classe Array
http://ruby-doc.org/core-2.0.0/Array.html#method-i-empty-3F
Viene utilizzato per verificare se l'array contiene qualcosa o meno. Questo include cose che valutano false
, come nil
e false
.
>> a = []
=> []
>> a.empty?
=> true
>> a = [nil, false]
=> [nil, false]
>> a.empty?
=> false
>> a = [nil]
=> [nil]
>> a.empty?
=> false
Il metodo any?
proviene dal modulo Enumerable.
http://ruby-doc.org/core-2.0.0/Enumerable.html#method-i-any-3F
Viene utilizzato per valutare se "qualsiasi" valore nell'array viene valutato true
. Metodi simili a questo sono none?
, all?
e one?
, dove tutti basta controllare per vedere quante volte vero potrebbe essere valutata. che non ha nulla a che fare con il conteggio dei valori trovati in un array.
caso 1
>> a = []
=> []
>> a.any?
=> false
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> true
caso 2
>> a = [nil, true]
=> [nil, true]
>> a.any?
=> true
>> a.one?
=> true
>> a.all?
=> false
>> a.none?
=> false
caso 3
>> a = [true, true]
=> [true, true]
>> a.any?
=> true
>> a.one?
=> false
>> a.all?
=> true
>> a.none?
=> false
Il prefisso dell'istruzione con un punto esclamativo consente di sapere se l'array non è vuoto. Quindi nel tuo caso -
a = [1,2,3]
!a.empty?
=> true
Evitare any?
per array di grandi dimensioni.
any?
è O(n)
empty?
è O(1)
any?
non controlla la lunghezza ma esegue la scansione dell'intero array alla ricerca di elementi veritieri.
static VALUE
rb_ary_any_p(VALUE ary)
{
long i, len = RARRAY_LEN(ary);
const VALUE *ptr = RARRAY_CONST_PTR(ary);
if (!len) return Qfalse;
if (!rb_block_given_p()) {
for (i = 0; i < len; ++i) if (RTEST(ptr[i])) return Qtrue;
}
else {
for (i = 0; i < RARRAY_LEN(ary); ++i) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
}
}
return Qfalse;
}
empty?
d'altra parte controlla solo la lunghezza dell'array.
static VALUE
rb_ary_empty_p(VALUE ary)
{
if (RARRAY_LEN(ary) == 0)
return Qtrue;
return Qfalse;
}
La differenza è rilevante se si hanno array "sparsi" che iniziano con molti nil
valori, come ad esempio un array appena creato.
nil
valori, con gli array "normali" any?
, senza dichiarazioni di blocco al primo elemento, quindi la complessità è ancora O (1) come il empty?
metodo di
Suggerirò di usare unless
e blank
per verificare che sia vuoto o meno.
Esempio :
unless a.blank?
a = "Is not empty"
end
Questo saprà "a" vuoto o no. Se 'a' è vuoto, il codice seguente non verrà eseguito.
#blank?
fa parte di Rails. Se stanno già usando Rails, #present?
è #blank?
comunque la negazione .
Non credo sia affatto male da usare any?
. Lo uso molto. È chiaro e conciso.
Tuttavia, se sei preoccupato per tutti i nil
valori che lo scaricano, allora stai davvero chiedendo se l'array ha size > 0
. In tal caso, questa semplice estensione morta (NON ottimizzata, in stile scimmia) ti avvicinerebbe.
Object.class_eval do
def size?
respond_to?(:size) && size > 0
end
end
> "foo".size?
=> true
> "".size?
=> false
> " ".size?
=> true
> [].size?
=> false
> [11,22].size?
=> true
> [nil].size?
=> true
Questo è abbastanza descrittivo, logicamente chiedendo "questo oggetto ha una dimensione?". Ed è conciso e non richiede ActiveSupport. Ed è facile da costruire.
Alcuni extra a cui pensare:
present?
di ActiveSupport.String
, che ignora gli spazi bianchi (come present?
fa).length?
per String
o di altro tipo in cui potrebbe essere più descrittivo.Integer
e altri Numeric
tipi, in modo che ritorni uno zero logico false
.
empty?
?