2010-11-10 7 views
9

C'è un modo più breve di testare il seguente:Come posso verificare che più booleani abbiano valori identici in C#?

if (!((a == b) && (a == c) && (a == d) && (a == e) && (a == f))) 

ho finito per scrivere un metodo che mi permette di fare questo

if (!AllEqual(new[] { a, b, c, d, e, f })) 

che si sente più bello ed è molto più leggibile, ma io' Mi chiedo se c'è qualcosa nel quadro che lo fa già?

+2

La tua soluzione è la più bella che riesco a pensare in cima alla mia testa. –

risposta

13

Bene per prima cosa, è possibile utilizzare una matrice di parametri per rendere più semplice:

public static bool AllEqual<T>(params T[] values) 
... 


if (AllEqual(a, b, c, d, e, f)) 
{ 
    ... 
} 

Non credo che troverete qualcosa di più semplice di quello, ad essere onesti. Non l'ho visto da nessun'altra parte o nel framework. Bene, suppongo che ci sia una cosa che potreste fare in LINQ:

if (new { a, b, c, d, e, f }.Distinct().Count() == 1) 

Ma questo è abbastanza orribile :)

Una versione leggermente più efficiente e cioè:

if (!(new { a, b, c, d, e, f }).Distinct().Skip(1).Any())) 

.. . che restituirà false non appena trova il secondo elemento distinto. Con solo 6 elementi non penso che valga la pena di preoccuparsi però :)

+0

+1 E suggerisco anche a OP di non usare 6 variabili bool, ma un 'bool []', che è anche più facile da interrogare con '.Distinct'. –

+0

@Danny: Penso che dipenda dal contesto - se le variabili hanno significati molto distinti che semplicemente hanno senso, tenerle separate ha senso. Se sono più simili, ad es. "il campo 1 è compilato, il campo 2 è compilato" ecc., quindi un array sarebbe effettivamente migliore. –

+0

Grazie per l'idea dell'array param. Rende la chiamata più semplice. –

0

Non credo sia una buona idea introdurre una dipendenza in un framework solo per quello.

+3

Ha detto * il * framework - come nel framework .NET principale, immagino. –

+0

Scusa, hai ragione. – Simone

0

Questo non è qualcosa che la gente di solito vuole sapere. Potresti facilmente verificare che erano tutti veri solo ed unendoli insieme, o che erano tutti falsi con i loro non-amici. È anche popolare in C++ per lanciare bool in ints e aggiungerli: nel tuo caso, sei in cerca di un totale di 6 o 0. Ma penso che entrambi oscurerebbero qualunque ragione di business tu abbia per sapere che 6 flag sono o tutto vero o tutto falso.

1

È possibile distribuire il! nell'espressione:

if ((a != b) || (a != c) || (a != d) || (a != e) || (a != f))) 

È inoltre possibile utilizzare Any o! All anziché aggiungere un nuovo metodo.

if (new[]{b, c, d, e, f}.Any(x => x != a)) ... 
2

Solo se a, b, c, d, e ed f sono valori booleani:

il modo più bello è quello di dare uno sguardo in Boolean logic e logic gates per simplify l'equazione.

(Il == è come un XNOR gate per i valori booleani)

Un esempio per voi:

(!((a == b) && (a == c) && (a == d) && (a == e) && (a == f))) 

è lo stesso di:

((a^b) || (a^c) || (a^d) || (a^e) || (a^f)) 

ma penso che deve essere interessante fare a una rivista della logica che viene a quello

[EDIT] In relazione con l'Hightechrider's answers, la proposizione

((a^b) || (a^c) || (a^d) || (a^e) || (a^f)) 

è equivalente a:

((a != b) || (a != c) || (a != d) || (a != e) || (a != f)) 

Ma Hightechrider's proposition funzionare perfettamente anche se a, b, c, d, e ed f non sono booleani .

+0

Stavo mirando alla leggibilità. Anche se questo è interessante, non sono sicuro di poterlo leggere domani. –

+0

Posso comprenderti se non sei consapevole della logica booleana: mi ci è voluto un po 'per abituarmi. comunque penso che sia molto importante pensare di imparare, anche se in questo caso la risposta di Jon Skeet sembra essere la soluzione migliore, rispetto alla tua domanda ^^ –

+1

Ovviamente, sono d'accordo che la forma completamente fattorizzata/semplificata di un booleano complesso l'espressione è davvero difficile da comprendere senza un rapido commento con la sua forma sviluppata –

1

È possibile utilizzare questo per controllare che sono tutte vere:

if (a && b && c && d && e && f) { 
    ... 
} 

e questo per verificare che esse sono tutte false:

if (!(a || b || c || d || e || f)) { 
    ... 
} 

e si potrebbe combinare sia per verificare che essi siano tutti uguali:

if ((a && b && c && d && e && f) || !(a || b || c || d || e || f)) 
    ... 
} 

Ma francamente, questo non è meglio del tuo soluzione originale :-)

base a quanto precede, ecco una possibile implementazione di AllEqual:

public static bool AllEqual(bool[] values) 
{ 
    bool andTerm = true; 
    bool orTerm = false; 
    foreach (bool v in values) 
    { 
     andResult &= v; 
     orResult |= v; 
    } 
    return andTerm || !orTerm; 
} 
+2

False: in '(a && b && c&&&&&&&&&&====================================================== , la soluzione restituisce 'true', mentre' (! ((a == b) && (a == c) && (a == d) && (a == e) && (a == f))) ' return 'false', e'! (a || b || c || d || e || f) 'return' true' se a, b, c, d, e, ef sono 'false' considerando' (! ((a == b) && (a == c) && (a == d) && (a == e) && (a == f))) 'return' false' ... E il terzo sempre return 'true' quando a, b, c, d, eef sono uguali, a differenza di' (! ((a == b) && (a == c) && (a == d) && (a == e) && (a == f))) 'che restituisce sempre' false' in questo caso ... –

+0

@G. Qyy: Il titolo della domanda dice: "Come posso verificare che più booleani abbiano ** valori identici ** in C#?". I frammenti di codice nella domanda lo usano effettivamente per verificare che i valori siano ** non ** uguali, ma una funzione 'AllEqual' è ciò che l'OP chiede esplicitamente. La mia risposta spiega: 1) Come testare per tutto vero, 2) Come testare per tutti i falsi, 3) Come testare per tutti uguali. Il mio codice fa quello che dico che fa. – Grodriguez

+0

Hai ragione su questo punto: capisco che vuole riprodurre il comportamento del suo primo test, e mi interessa un po 'di titolo perché raramente espongono la completa complessità della domanda ... Naturalmente, il tuo codice è giusto rispetto a quello che dici che fa. le mie scuse ^^ –

1

Uso BitArray:

Gestisce una matrice compatta di valori di bit, che sono rappresentati come booleani, dove true indica che il bit è su (1) e false indica che il bit è disattivato (0).

// Your collection of bits 
bool a = false, b = false, c = false; 
// get them into an array 
bool[] d = new bool[] { a, b, c }; 
// intialize BitArray with that array 
System.Collections.BitArray e = new System.Collections.BitArray(d); 
// use OfType<>, Any<>, All<> 
if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is TRUE!."); 

Un esempio di codice di applicazione console per la dimostrazione:

class Program 
    { 
     static void Main(string[] args) 
     { 
      bool a = false, b = false, c = false; 
      bool[] d = new bool[] { a, b, c }; 
      System.Collections.BitArray e = new System.Collections.BitArray(d); 
      if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is TRUE!."); 
      if (Convert.ToBoolean(e.OfType<bool>().Any<bool>(condition => condition.Equals(true)) && e.OfType<bool>().Any<bool>(condition => condition.Equals(false)))) Console.WriteLine("some one is FALSE!."); 
      if (Convert.ToBoolean(e.OfType<bool>().All<bool>(condition => condition.Equals(true)))) Console.WriteLine("All of them are TRUE!."); 
      if (Convert.ToBoolean(e.OfType<bool>().All<bool>(condition => condition.Equals(false)))) Console.WriteLine("All of them are false!."); 
      Console.ReadLine(); 
     } 
    } 

MSDN documentazione sulBitArray

1

ne dite ..

List<bool> arr = new List<bool>{ a, b, c, d, f }; 
bool allEqual = arr.TrueForAll(x => { return x; }) || arr.TrueForAll(x => { return !x; }); 

Looks abbastanza elegante per me. :)

Problemi correlati