web-dev-qa-db-fra.com

Comparaison d'égalité entre plusieurs variables

J'ai une situation où je dois vérifier si plusieurs variables ont les mêmes données telles que

var x=1;
var y=1;
var z=1;

Je veux vérifier si x == 1 et y == 1 z == 1 (il peut s'agir de '1' ou d'une autre valeur). au lieu de cela, y a-t-il un chemin court que je peux atteindre comme ci-dessous

if(x==y==z==1)

Est-ce possible en C #?

32
JPReddy

KennyTM est correct, il n'y a pas d'autre moyen plus simple ou plus efficace.

Toutefois, si vous avez plusieurs variables, vous pouvez également créer un tableau des valeurs et utiliser la méthode IEnumerable.All pour vérifier qu'elles sont toutes 1. Plus lisible, IMO. 

if (new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 }.All(x => x == 1))

Au lieu de

if(v1 == 1 && v2 == 1 && v3 == 1 && v4 == 1 && v5 == 1 && v6 == 1 && v7 == 1 && v8 == 1 && v9== 1 && v10 == 1)
54
jevakallio
if (x == y && y == z && z == 1)

est le mieux que vous puissiez faire, car

y == z est évalué à un booléen et vous ne pouvez pas comparer x avec le résultat:

x == (y == z)

|    |

int  bool

Je voudrais faire ceci:

public bool AllEqual<T>(params T[] values) {
    if(values == null || values.Length == 0)
         return true;
    return values.All(v => v.Equals(values[0]));    
}

// ...

if(AllEqual(x, y, z)) { ... }
28
Mau

Si vous voulez juste tester x == y == z, vous pouvez utiliser:

var allEqual = new[] {x, y, z}.Distinct().Count() == 1;

Si vous voulez tester s'ils sont tous égaux à 1, ajoutez 1 à l'ensemble:

var allEqual1 = new[] {x, y, z, 1}.Distinct().Count() == 1;

ou utilisez All comme dans la réponse de fencliff.

22
Jamie Ide
if (x == y && y == z && z == 1)

Il n'y a pas d'autres moyens simples ou plus efficaces.

9
kennytm

Voici une jolie petite solution récursive qui fonctionne avec tous les types.

class Program
{
    static void Main(string[] args)
    {
        int x = 4, y = 4, z = 4;
        Console.WriteLine(4.IsEqualToAllIn(x, y, z).ToString());
        //prints True

        string a = "str", b = "str1", c = "str";
        Console.WriteLine("str".IsEqualToAllIn(a, b, c).ToString());
        //prints False
    }
}

public static class MyExtensions
{
    public static bool IsEqualToAllIn<T>(this T valueToCompare, params T[] list)
    {
        bool prevResult = true;
        if (list.Count() > 1)
            prevResult = list[0].IsEqualToAllIn(list.Skip(1).ToArray());
        return (valueToCompare.Equals(list[0])) && prevResult;
    }
}
4

Pour les types intégraux, qu'en est-il:

int x = 3, y = 3, z = 3;

if((x & y & z & 3) == 3)
  //...have same data

pour tester tout différent de zéro valeur ... Il faudra plus de contrôles pour en faire une fonction réutilisable. Mais pourrait fonctionner pour des contrôles en ligne d'égalité non nulle, comme décrit dans l'OP.

4
mdisibio
public static bool AllSame<T>(List<T> values)
{
    return values.Distinct().Count() == 1;
}

public static bool AllDifferent<T>(List<T> values)
{
    return values.Distinct().Count() == values.Count;
}
3
soycd

XOR peut fonctionner pour vous, par exemple donné:

var x=1;
var y=1;
var z=1;

Ensuite

x ^ y ^ z == 0

Est vrai

-edit - Si vous voulez vérifier si toutes les valeurs sont identiques et leur valeur est 1, utilisez:

x ^ y ^ z ^ 1 == 0
1
Żubrówka

Ajouter cette extension:

public static class Extensions
{
    public static bool EqualsAll<T>(this T subject, params T[] values) =>
        values == null || values.Length == 0 || values.All(v => v.Equals(subject));
}

Alors appelle ça comme ça:

if(1.EqualsAll(x, y, z))
1
oddRaven

Légère variation sur l'excellente réponse donnée par jevakallio ci-dessus. Voir si maValeur est égale à l'une des valeurs d'une liste (dans le tableau):

if (new[] { 10, 11, 12 }.Any(x => x == myValue))
0
Julian Rosebury
var x = 1;
var y = 1;
var z = 1;

if (AllEqual(1, x, y, z))    // true
if (AllEqual(2, x, y, z))    // false
if (AllEqual(x, y, z))       // true

var a = 1;
var b = 2;
var c = 3;

if (AllEqual(a, b, c))       // false

// ...

public static bool AllEqual<T>(params T[] values)
{
    if (values == null)
        throw new ArgumentNullException("values");

    if (values.Length < 1)
        throw new ArgumentException("Values cannot be empty.", "values");

    T value = values[0];
    for (int i = 1; i < values.Length; i++)
    {
        if (!value.Equals(values[i]))
            return false;
    }
    return true;
}
0
LukeH

Voici comment j'ai fait ceci:

Debug.Assert(new List<int> { l1.Count, l2.Count, l3.Count, l4.Count }.TrueForAll(
  delegate(int value) { return value == l1.Count; }), "Tables have different size.");
0
Elephant

J'ai adapté la solution de Mau à une méthode d'extension. Ce serait bien s'ils ajoutaient cela au cadre pour tous les types de valeur.

public static class IntegerExtensions
{
    public static bool EqualsAll(this int subject, params int[] values)
    {
        if (values == null || values.Length == 0)
        {
            return true;
        }

        return values.All(v => v == subject);
    }
}
0
magritte

En fait, je n'ai pas le temps de coder, mais une méthode d'extension avec linq comme celle-ci

public bool EqualsToAll<T>(this T element, IEnumerable<T> source)
{
    if(element == null)
        throw new ArgumentNullException(element);

    foreach(var item in source)
    {
        if(!element.Equals(item)
            return false;
    }

    return true;
}

devrait le faire.

Attention: Ce code n'a pas été testé, ni écrit dans un IDE.

0
Oliver