czhili
czhili

Reputation: 83

Comparing values of arrays in C#

I have a bool array that looks like this

bool[] responses = new bool[] {true, false, true};

And two classes that look like this:

public class Person {
  public IList<PersonDetail> PersonDetails
}

public class PersonDetail {
  public bool   Correct { get; set; }
}

PersonDetails
 >> PersonDetail[0].correct = true
 >> PersonDetail[1].correct = true
 >> PersonDetail[2].correct = false

Is there a simple way I can compare these to see if the true/false are equal for each? I was trying to use the c# .SequenceEqual but I don't know how to get the data from the PersonDetail class into a sequence xxx that I can use to compare with responses.

Here's what I have so far:

var equal = responses.Select(bool.Parse).SequenceEqual( xxx );

What I need to do is to compare the following:

responses[0] == PersonDetail[0].correct and
responses[1] == PersonDetail[1].correct and
responses[2] == PersonDetail[2].correct 

So what's true in responses[x] should match true in PersonDetail[x] and what's false in responses[x] should match false in PersonDetail[x]

Upvotes: 1

Views: 560

Answers (8)

Zenwalker
Zenwalker

Reputation: 1919

Use XOR and not AND or OR operations on these items. XOR table will give you 0 if both items are the same.

Upvotes: 0

user159335
user159335

Reputation:

Doesn't get much simpler than:-

  if (person.PersonDetails.Count != responses.Length)
    throw new ArgumentOutOfRangeException("Arrays are different lengths");
  bool result = true;
  for (int i = 0; i < person.PersonDetails.Count; i++)
  {
    if (person.PersonDetails[i].Correct != responses[i])
    {
      result = false;
      break;
    }
  }

Every programmer on the planet will be able to read it, even if they've never seen c#.

Actually it highlights a missing aspect of the spec; What should happen if the lists are different lengths?

Upvotes: 0

MarcE
MarcE

Reputation: 3731

If I'm reading your question correctly, this LINQ will do what you ask. I'm not sure it's more readable than a simple foreach loop but that's not the point!

public class Person 
{
  public IList<PersonDetail> PersonDetails;
}

public class PersonDetail 
{
  public bool   Correct;
}

void Main()
{
    bool[] responses = new bool[] {true, false, true};
    Person p = new Person();
    p.PersonDetails = new List<PersonDetail>();
    p.PersonDetails.Add(new PersonDetail(){Correct = true});
    p.PersonDetails.Add(new PersonDetail(){Correct = true});
    p.PersonDetails.Add(new PersonDetail(){Correct = false});

    //bool allGood = p.PersonDetails.Select((pd, index) => pd.Correct == responses[index]).All(x => x==true);

    bool allGood = responses.SequenceEqual(p.PersonDetails.Select(x => x.Correct));
    allGood.Dump(); // LINQpad extension
}

[edit - OK, so it's early and I forgot about SequenceEquals which does the same thing in a much more readable manner. Code changed to match what everyone else already answered...].

Upvotes: 1

Harag
Harag

Reputation: 1582

From the answers already given I've had a play around and come up with the below, seems to work - note that I'm also new to C# so this has been an interesting problem.

As JonB points out in one of the answers - what happens if the lengths of "responses" and "people" are different... Hope the below helps

class Program
{       
    static void Main(string[] args)
    {
        bool[] responses = new bool[] { true, false, true };

        Person people = new Person();
        people.PersonDetails.Add(new PersonDetail() { Correct = true });
        people.PersonDetails.Add(new PersonDetail() { Correct = false });
        people.PersonDetails.Add(new PersonDetail() { Correct = true });

        bool equal = responses.SequenceEqual(people.PersonDetails.Select(P=> P.Correct));
        Console.WriteLine (equal);
    }
}

public class Person
{
    public List<PersonDetail> PersonDetails = new List<PersonDetail>();
}

public class PersonDetail
{
    public bool Correct;
}

Upvotes: 1

Jonas Elfstr&#246;m
Jonas Elfstr&#246;m

Reputation: 31428

You can use SequenceEqual like this

var responses = new [] { true, false, true };
var details = new List<PersonDetail>()
                { new PersonDetail() {Correct = true},
                  new PersonDetail() {Correct = false},
                  new PersonDetail() {Correct = true} };
var person = new Person() { PersonDetails = details };

var equal = responses.SequenceEqual(person.PersonDetails.Select(pd => pd.Correct));

Upvotes: 1

Patrick
Patrick

Reputation: 1148

You could also try something like this:

IEnumerable<bool> answers = from x in Person.PersonDetails select x.correct;
bool equal = responses.SequenceEqual(answers)

Upvotes: 0

George Duckett
George Duckett

Reputation: 32428

Not 100% sure of your code, but maybe:

var equal = responses.SequenceEqual(Person.PersonDetails.Select(PD => PD.correct);

Upvotes: 0

Freek
Freek

Reputation: 1516

Your code isn't really clear, but I imagine you want to do the following:

var isEqual = responses.SequenceEqual(PersonDetail.Select(p=>p.Correct))

Upvotes: 1

Related Questions