1

I've data in two ArrayList arrayListA and arrayListB.

I want to do a check if there is a difference between these two arrayLists.

so i do this in the code :

 ArrayList diff = new ArrayList();
 foreach (string[] a in arrayListB)
 {
     if(!arrayListA.Contains(a))
     {
         diff.Add(a);
     }
 }

so my problem here when I run the program. All data in arrayListB is added into ArrayList diff. It should only add the data that is only in arrayListA and not arrayListB, correct?

what is going wrong?

This is the result after i run the program. The listbox a is data in arrayListA, listbox B is data in arrayListB and listbox diff is data from diff. EDIT

I already enter System.Linq.

but i don't get "Where" properties for my List.

haih

Qusyaire Ezwan
  • 279
  • 4
  • 8
  • 18

4 Answers4

4

Since you are using an array list of arrays of strings, the Contains method is not going to work: it uses Equals method to check for equality, but the implementation of Equals in C# arrays does not pay attention to the equality of array elements.

Here is a link to the question discussing the problem of checking array equality in C#.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

First of all, it would be easier to work with List:

List<string[]> listA = new List<string[]>();
List<string[]> listB = new List<string[]>();

Now you can use Linq to get the ones that are in A but not in B, and the ones that are in B but not in A, and combine those to get the complete difference:

using System.Linq;

...

List<string[]> diff =
    listA.Where(a => !listB.Any(a.SequenceEqual)).Union(
    listB.Where(b => !listA.Any(b.SequenceEqual))).ToList();

Translation of the code above, with simple loops and longer code is:

private List<string[]> GetDiff(List<string[]> listA, list<string[] listB>)
{
    var diff = new List<string[]>();

    foreach (var a in listA)
    {
        bool found = false;

        foreach (var b in listB)
        {
            if (a.SequenceEqual(b))
            {
                found = true;
                break;
            }
        }

        if (!found)
        {
            diff.Add(a);
        }
    }

    foreach (var b in listB)
    {
        bool found = false;

        foreach (var a in listA)
        {
            if (b.SequenceEqual(a))
            {
                found = true;
                break;
            }
        }

        if (!found)
        {
            diff.Add(b);
        }
    }

    return diff;
}
SimpleVar
  • 14,044
  • 4
  • 38
  • 60
  • the "where" properties. i don't get it. that i need to enter any reference to use it? – Qusyaire Ezwan Jun 14 '12 at 07:30
  • The Where is an extension method. To put simply - it works on a collection and filters it according to a certain condition (given each element the name `a`, take only the ones that satisfy `!listB.Any(a.SequenceEqual)`. The Any is also an extension method (they got so popular, tehe), which returns whether at least one element satisfied the condition (each element is being tested in `a.SequenceEqual`). – SimpleVar Jun 14 '12 at 07:33
  • @QusyaireEzwan Oh, and to use them, you need to add reference to `System.Linq` - added to answer. Also added to answer a translation of the code that uses the Linq extension methods, so you can fully understand how they work and what they do. – SimpleVar Jun 14 '12 at 07:33
  • Where did you put it? You should write `using System.Linq` at the top of your file, near the other usings. Anyway, you could use the non-Linq version if you are having troubles with referencing the Linq extension methods. – SimpleVar Jun 14 '12 at 07:43
  • there is because of im using VS 2005? – Qusyaire Ezwan Jun 14 '12 at 07:45
  • Oh yes, you don't have that then. Use the 2nd version of code I provided - it does the same exactly, except it's more code to look at. Wrap it with a method and you're good. – SimpleVar Jun 14 '12 at 07:46
1

Assume both arrayListB and contains array of strings then you can try as

 ArrayList diff = new ArrayList();
 foreach (var b in arrayListB)
 {
     bool found = false;
     foreach (var a in arrayListA)
     {
        if(Enumerable.SequenceEqual(a as string[], b as string[]))
        {
          found = true
          break;
        }
     }
     if(!found)
     {
        diff.Add(b);
     }
 }
Damith
  • 62,401
  • 13
  • 102
  • 153
  • First of all, it should be `!SequenceEqual`, and you can use it as an extension method which is nicer to look at. Second, you won't get the difference between the lists, you will only get the elements that were in B but weren't in A. – SimpleVar Jun 14 '12 at 07:21
0

There is no built in Equal for string[] that makes Contains work the way you probably want. You need to implement custom comparison for string[] and use the other override of Contains that takes comparer as argument.

As side note it would be better to use strongly typed lists to start with like List<string[]>.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179