Home > database >  c# array merge without dupes. I cant use Linq and Lists
c# array merge without dupes. I cant use Linq and Lists

Time:11-15

Let's say I have these two arrays:

string[] arr1 = new string[2]{"Hello", "Stack"}
string[] arr2 = new string[2]{"Stack", "Overflow"}

How would I merge them to get a third array like so:

string[3]{"Hello", "Stack", "Overflow"}

CodePudding user response:

If order is unimportant, a hashset will work

var hs = new HashSet<string>(arr1);
hs.UnionWith(arr2);

var arr3 = new string[hs.Count];
hs.CopyTo(arr3);

If order is important, you can pair a hashset and a linked list; the hashset remembers things we saw before:

var hs = new HashSet<string>(arr1);
var ll = new LinkedList<string>(arr1);

foreach(var x in arr2)
  if(hs.Add(x))
    ll.Add(x);

var arr3 = new string[hs.Count];
ll.CopyTo(arr3);

A hashset's Add Method only returns true if the item was added - if we've already seen the item then it will not be added. This means if we only add to the LinkedList when we have successfully added to the HashSet then the LinkedList will end up with a unique set of elements in the original order as presented in the arrays. Note that this as presented doesn't dedupe the first array within itself. If the first array will have duplicates then instead of passing it to LinkedList's constructor, you should run two foreach loops i.e. process process both arrays like the second array is processed here

CodePudding user response:

Well, let's use HashSet<string> to check for duplicates (fiddle). The code below preserves the initial order:

{"Hello", "Stack"}   {"Stack", "Overflow"} ==
{"Hello", "Stack", "Stack", "Overflow"}    =>
{"Hello", "Stack", "Overflow"}

Code:

 // arr1.Length   arr2.Length is maximum possible length
 string[] result = new string[arr1.Length   arr2.Length];

 HashSet<string> unique = new HashSet<string>();

 for (int i = 0; i < arr1.Length   arr2.Length;   i) {
   // an item can be from arr1 or arr2
   string item = i < arr1.Length ? arr1[i] : arr2[i - arr1.Length];

   // if we have an unique item
   if (unique.Add(item))  
     result[unique.Count - 1] = item; // we put it to result at its place
 }

 // Since we may have got duplicates, we have to ajust result size
 Array.Resize(ref result, unique.Count);

 // Let's have a look at result
 Console.Write(string.Join(" ", result));

If HashSet<T> as well as any other collections (List<T>, LinkedList<T> etc.) are forbidden we can scan result to check duplicates:

Array Only Code:

 // arr1.Length   arr2.Length is maximum possible length
 string[] result = new string[arr1.Length   arr2.Length];

 int index = 0;

 for (int i = 0; i < arr1.Length   arr2.Length;   i) {
   // an item can be from arr1 or arr2
   string item = i < arr1.Length ? arr1[i] : arr2[i - arr1.Length];

   // Do we have an unique item?
   bool duplicate = false; 

   for (int j = 0; j < index;   j)
     if (item == result[j]) {
       duplicate = true;

       break;
     }

   if (!duplicate) 
     result[index  ] = item;
 }

 // Since we may have got duplicates, we have to ajust result size
 Array.Resize(ref result, index);

 // Let's have a look at result
 Console.Write(string.Join(", ", result));
  • Related