2011-11-14 20 views
8

Salve dire che ho tre interi: valore1, valore2 e valore3.Come determinare se tre interi sono tutti uguali

Come determinare se sono tutti uguali?

Ho provato:

return value1 == value2 == value3 

Ma questo detto:

operatore '==' non può essere applicato a operandi di tipo 'bool' e 'int'.

Quindi suppongo che confronta i primi due che restituisce un valore booleano che tenta di confrontare con il terzo.

Potrei andare:

return value1 == value2 && value2 == value3; 

Ma questo sembra essere sempre in disordine.

Qualcuno ha un buon suggerimento?

+1

maggior parte dei linguaggi non supportano la vostra prima sintassi (l'unica lingua che so che * fa * supporta che la sintassi è Python). – NullUserException

risposta

5

Il secondo mi sembra perfetto.

Man mano che la lista si allunga, potrebbe diventare difficile. In tal caso, scriverei un metodo di estensione lungo le linee AllSame.

bool AllSame(this IEnumerable<int> list) 
{ 
    bool first = true; 
    int comparand = 0; 
    foreach (int i in list) { 
     if (first) comparand = i; 
     else if (i != comparand) return false; 
     first = false; 
    } 
    return true; 
} 

o utilizzare la parola chiave params:

bool AllSame(params int[] list) 
{ 
    return (list as IEnumerable<int>).AllSame(); 
} 

allora si può solo scrivere:

if (AllSame(value1, value2, value3, value4, value5)) ... 
+0

motivo per downvote? –

+0

Posso credere che questo sia stato selezionato come risposta corretta ... poiché esiste già un metodo di estensione ** Tutti **. –

+0

@parapurarajkumar, 'Tutto()' fa qualcosa di diverso. E se intendevi qualcosa come 'list.All (x => x == list.First())', allora non funzionerebbe per le raccolte che possono essere ripetute una sola volta. – svick

3

che sembra che vada bene per me. L'unico commento che ho è che dovresti introdurre una "variabile esplicativa" per l'equazione. Oltre a spiegare il calcolo, il ritorno ora fornisce un bel posto per un punto di interruzione o un punto di tracciamento durante l'ispezione del risultato.

bool allThreeAreEqual = value1 == value2 && value2 == value3; 
return allThreeAreEqual; 
0

Se siete solo in cerca di eleganza (Considerando il tuo hanno già una soluzione che non ha niente di sbagliato con esso), si potrebbe andare con good'ol LINQ. Questo può gestire tre o più.

class Program 
    { 
     static void Main(string[] args) 
     { 
      List<int> mylist = new List<int>(); 
      mylist.Add(1); 
      mylist.Add(1); 
      mylist.Add(1); 
      mylist.Add(1); 

      bool allElementsAreEqual = mylist.All(x => (x == mylist.First())); 
     } 
    } 
+0

Dubito che tornerà più veloce ... Non c'è nulla in ** Tutti ** che rende necessario esaminare tutti gli elementi ... –

+0

per qualche motivo ho avuto due thinko di fila. Sry. – sehe

+0

Se uno di essi non corrisponde ... Tutto restituisce falso, Se due di essi non corrispondono restituisce falso ... Quindi, non appena Tutti trova uno di essi non soddisfa il predicato, non ha bisogno di valutare il predicato sui restanti elementi. Stai dicendo che non è il caso? La documentazione MSDN menziona ** L'enumerazione della fonte viene interrotta non appena il risultato può essere determinato. ** –

4

Ho modificato la mia risposta originale per includere un metodo più generale e che non si basa su LINQ o metodi di estensione. Penso che sia sicuro assumere che questo metodo sarebbe più performante basato sul fatto che non è necessario enumerare l'intero elenco per determinare l'unicità quando ci sono valori che sono diversi all'inizio nella lista.

class Program 
{ 
    static void Main(string[] args) 
    { 
     int value1 = 1, value2 = 2, value3 = 1; 
     Console.WriteLine(AllAreEqual<int>(value1, value2, value3)); 

     Console.Write("V2: 1 value "); 
     Console.WriteLine(AllAreEqual_V2<int>(1)); 

     Console.Write("V2: no value "); 
     Console.WriteLine(AllAreEqual_V2<int>()); 

     Console.Write("V2: 3 values, same "); 
     Console.WriteLine(AllAreEqual_V2<int>(1, 1, 1)); 

     Console.Write("V2: 3 values, different "); 
     Console.WriteLine(AllAreEqual_V2<int>(1, 1, 2)); 

     Console.Write("V2: 2 values, same "); 
     Console.WriteLine(AllAreEqual_V2<int>(1, 1)); 

     Console.Write("V2: 2 values, different "); 
     Console.WriteLine(AllAreEqual_V2<int>(1, 2)); 

     Console.ReadKey(); 
    } 

    static bool AllAreEqual<T>(params T[] args) 
    { 
     return args.Distinct().ToArray().Length == 1; 
    } 

    static bool AllAreEqual_V2<T>(params T[] args) 
    { 
     if (args.Length == 0 || args.Length == 1) 
     { 
      return true; 
     } 

     if (args.Length == 2) 
     { 
      return args[0].Equals(args[1]); 
     } 

     T first = args[0]; 

     for (int index = 1; index < args.Length; index++) 
     { 
      if (!first.Equals(args[index])) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 
} 
+3

+1; 'ToArray(). Length == 1' può essere compattato in' Count() == 1'. –

+0

O_o. Wow. Questo è lo scopo generale. –

+0

Grazie Merlyn, apprezza la raffinatezza. –

0
int nOneInput = 5; 
int nTwoInput = 5; 
int nThreeInput = 5; 
if ((nOneInput + nTwoInput + nThreeInput)/3 == nOneInput) 
{ 
    // all 3 sides are equal when... 
    // the sum of all 3 divided by 3 equals one of the values 
} 
+0

Un modo semplice ... –

+2

Questo può essere sbagliato se hai qualcosa come {5, 4, 6}. La media sarebbe comunque 5, ma non sarebbe possibile determinare se tutti e 3 sono uguali. – bfs

0

utilizzando LINQ sarebbe meglio per noi Any(). Perché Any() anziché All() è perché All() verificherà il predicato su tutti gli elementi della raccolta mentre Any() uscirà non appena e l'elemento corrisponde al predicato.

Qui utilizzo un controllo inverso. Sto cercando qualsiasi oggetto che sarà diverso dall'elemento "a".Quindi appena ne trova una diversa, sappiamo che non sono tutti uguali, quindi esce e restituisce true. Quindi testerà solo le voci "b", "c" e "d".

// all values to compare 
var a = 4; 
var b = 4; 
var c = 4; 
var d = 8; 
var e = 6; 
var f = 4; 

// return if any of the following is different and negate to get a true 
var areSame = (!new[] { b, c, d, e, f}.Any(i => i != a)); 

Se si sovrascrive equals è possibile creare estensioni generiche di questo che è riutilizzabile e può lavorare per il tipo più il tempo che implementano IEqualityComparer<T>

Problemi correlati