Hello,
I have 2 sorted array lists.
e.g. arrayList1 = a,b,c,d,e,f,h,k,l and arrayList2 = a,c,d,f,g,h,i,j
ArrayList1 contains the list of strings that are to be compared against. Unfortunately there are thousands of strings in each. So I don't know if it would be any good doing something like; does arrayList[0] == arrayList[0]||arrayList[1]||.... (in a loop of course).
Another thing, arrayList2 is getting its (distinct) data from a database so I can't really check it against arrayList1 there and then, as it would leave the connection open for longer... I don't know maybe this is an ok trade off
I don't suppose there is an efficient arrayList1.compare(arrayList2) method out there Or some other alternative.
Thanks.

Compare ArrayList
Pedro Martins
or something like
foreach item in arrayList1
if (arrayList2.binarysearch(item) < 0)
arrayListDiscrepency.add(item)
...
abrewerton
ok, which is a better method Your way, or this way (arrayList1 can be 1000+ strings, and arrayList2 can be 500 strings->
arrMissingCodes = compareArrays(arrCodesList, arrDB);
private
string compareArrays(ArrayList ar1, ArrayList ar2){
StringBuilder sb =
new StringBuilder();ar1.Sort();
ar2.Sort();
foreach (string item in ar1){
if(ar2.BinarySearch(item) < 0){
sb.Append(item + ", ");
}
}
return sb.ToString();}
Juliano.net
Here you go, this should work:
using System;
using System.Collections;
using System.Text;
using System.Collections.Specialized;
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
SortedList list1 = new SortedList();
SortedList list2 = new SortedList();
list1.Add("A", null);
list1.Add("B", null);
list1.Add("C", null);
list1.Add("D", null);
list1.Add("E", null);
list1.Add("F", null);
list1.Add("G", null);
list1.Add("K", null);
list2.Add("A", null);
list2.Add("B", null);
list2.Add("C", null);
list2.Add("D", null);
list2.Add("E", null);
list2.Add("F", null);
list2.Add("G", null);
list2.Add("K", null);
bool equal = Compare(list1, list2);
if (equal)
{
Console.WriteLine("They're the same!");
}
else
{
Console.WriteLine("They differ");
}
}
static bool Compare(SortedList list1, SortedList list2)
{
// Early check for difference
if (list1.Count != list2.Count)
{
return false;
}
IDictionaryEnumerator iter = (IDictionaryEnumerator)list1.GetEnumerator();
// Compare each value in list 1 with each value in list 2
while( iter.MoveNext() )
{
if (!list2.ContainsKey((string)iter.Key))
{
// Return the moment we find a difference
return false;
}
}
// Must be the same
return true;
}
}
}
davidmvp
I'm thinking of doing something like this: The Call, and below that the function
if(sb.Length != codesList.Length)
{
string diff = getDiferences(sb, codesList);
throw new System.ArgumentException("The following codes do not exist in the database, please ammend the input file: " + diff );
}
private
string getDiferences(StringBuilder sb, string codesList){
string sRetVal = null;//The sb are the origionals and codesList has to be checked against it
//the strings look like this: 'IRE','ENG','SCO'
//So I will split the strings in codesList and check each one sb.contains(codesListArray[ i ])
//if it exists, should I remove it from both... to bring the computation down There could be 10000 codes in the DB and 400 in the file
//if it doesn't exsist add it to the string sRetVal
return sRetVal;
}
jshtz4
fiaolle
My way would be much faster as it works with lists which are already sorted (each item is sorted as you add it to the list). Also the SortedList works like a hash-table too which allows far faster random access. Doing a binary search would be far slower than doing hashtable access.
You could run the two side by side and profile them, but I think you'll find my solution will be orders of magnitude faster.
Mark Flamer
A__alex10
Here's a version that produces a list of items that are missing from the second list:
class Program
{
static void Main(string[] args)
{
SortedList list1 = new SortedList();
SortedList list2 = new SortedList();
list1.Add("A", null);
list1.Add("B", null);
list1.Add("C", null);
list1.Add("D", null);
list1.Add("E", null);
list1.Add("F", null);
list1.Add("G", null);
list1.Add("K", null);
list2.Add("C", null);
list2.Add("D", null);
list2.Add("E", null);
list2.Add("F", null);
list2.Add("G", null);
list2.Add("K", null);
SortedList notPresent = Compare(list1, list2);
if (notPresent.Count == 0)
{
Console.WriteLine("All items present in DB");
}
else
{
Console.WriteLine("These items are not present in DB");
IDictionaryEnumerator iter = (IDictionaryEnumerator)notPresent.GetEnumerator();
// Compare each value in list 1 with each value in list 2
while (iter.MoveNext())
{
Console.WriteLine(iter.Key.ToString());
}
}
}
static SortedList Compare(SortedList list1, SortedList list2)
{
SortedList notPresentList = new SortedList();
IDictionaryEnumerator iter = (IDictionaryEnumerator)list1.GetEnumerator();
// Compare each value in list 1 with each value in list 2
while( iter.MoveNext() )
{
if (!list2.ContainsKey((string)iter.Key))
{
notPresentList.Add(iter.Key, iter.Value);
}
}
return notPresentList;
}
}
Drew Marsh
Have a look at the abstract KeyedCollection class(http://msdn2.microsoft.com/en-us/library/ms132438.aspx) and the Hashtable.
"The KeyedCollection class provides both O(1) indexed retrieval and keyed retrieval that approaches O(1)."
Replace array2 bij a KeyedCollection or Hashtable and compare using the Contains method.
Cheers,
Wes
Kamii47
ReefDvrJim
Here's my take on it. It assumes that both lists are sorted, and returns the differences.
It is also O(N), while every other one presented here has been either O(N^2) or O(N ln N)
class ArrayCompare {
static public string Compare(IList list1, IList list2)
{
int i = 0;
int j = 0;
StringBuilder sb1 = new StringBuilder("Items missing from List2: ");
StringBuilder sb2 = new StringBuilder("Items missing from List1: ");
while (i < list1.Count)
{
if (j == list2.Count)
break;
IComparable obj1 = list1[ i ] as IComparable;
IComparable obj2 = list2[ j ] as IComparable;
int cmp =obj1.CompareTo(obj2);
switch (Math.Sign(cmp))
{
case 0:
++i;
++j;
break;
case 1: // list1
++j;
break;
case -1:
sb1.AppendFormat("\"{0}\", ", obj1);
++i;
break;
}
}
while (i < list1.Count) // we reached the end of list 2 first. {
sb1.AppendFormat("\"{0}\", ", list1[i]);
++i;
}
while (j < list2.Count) // we reached the end of list 1 first. {
sb2.AppendFormat("\"{0}\", ", list2[j]);
++j;
}
return sb1.ToString() + Environment.NewLine + sb2.ToString();
}
}
amagino
Just profiled the two:
Louthy method: Compare two random lists with 10000 items in each 31 milliseconds
Louthy method: Compare two identical lists with 10000 items in each 31 milliseconds
TheSniipe method: Compare two random lists with 10000 items in each 93 milliseconds
TheSniipe method: Compare two identical lists with 10000 items in each 125 milliseconds
Hope that helps :)
hye_heena
anyone got any ideas on this
matt01
A hashtable won't work as it won't keep the sorted order.
Use a SortedDictionary instead of an ArrayList, as that will allow for instant look-up of the key in the second list. I've provided an example below.
class Program
{
static void Main(string[] args)
{
SortedDictionary<string, object> list1 = new SortedDictionary<string, object>();
SortedDictionary<string, object> list2 = new SortedDictionary<string, object>();
list1.Add("A", null);
list1.Add("B", null);
list1.Add("C", null);
list1.Add("D", null);
list1.Add("E", null);
list1.Add("F", null);
list1.Add("G", null);
list2.Add("A", null);
list2.Add("B", null);
list2.Add("C", null);
list2.Add("D", null);
list2.Add("E", null);
list2.Add("F", null);
list2.Add("G", null);
list2.Add("K", null);
bool equal = Compare(list1, list2);
if (equal)
{
Console.WriteLine("They're the same!");
}
else
{
Console.WriteLine("They differ");
}
}
static bool Compare(SortedDictionary<string, object> list1, SortedDictionary<string, object> list2)
{
// Early check for difference
if (list1.Count != list2.Count)
{
return false;
}
// Compare each value in list 1 with each value in list 2
foreach (KeyValuePair<string, object> item in list1)
{
if (!list2.ContainsKey(item.Key))
{
// Return the moment we find a difference
return false;
}
}
// Must be the same
return true;
}
}