0
static List<int>Merge(List<int> list_a, List<int> list_b)
{
    List<int> list_c=new List<int>();
    
    int countA = 0, countB = 0;

        for (int i =0;i< list_a.Count + list_b.Count-2;i++)
        {
            if (list_a[countA]<=list_b[countB])
            {
                list_c.Add(list_a[countA]);
                countA ++;
            }
            else
            {
                list_c.Add(list_b[countB]);
                countB ++;
            }
        }
        return list_c;
    }

my idea was to go through the for loop as many times as how many element list_c will have at the end Compare each element in both list then add the smallest one in list_c i already have a way to check if both lists are in ascending order when im testing it with

List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)));

countB goes out of bound once the last element in list b is added, the next comparison in that for-loop is then invalid as its comparing list_b[3]

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Paris
  • 5
  • 2
  • Does this answer your question? [Joining two lists together](https://stackoverflow.com/questions/1528171/joining-two-lists-together) – Venkataraman R Aug 27 '21 at 07:40
  • You need 3 loops - first one where indexA and indexB are inside their respective lists, second one where indexA is inside its list and last one the same but for indexB. – Camilo Terevinto Aug 27 '21 at 07:51
  • 1
    @VenkataramanR That duplicate is for joining 2 lists together, while this question is for joining 2 lists together **in ascending order** – Camilo Terevinto Aug 27 '21 at 07:51
  • Just append one list to the other then sort? – T.Schwarz Aug 27 '21 at 07:54
  • 3
    `var merged = myList1.Union(myList2).ToList().Sort();` If you don't need to implement it yourself for some reason – Siavash Rostami Aug 27 '21 at 07:55
  • @T.Schwarz that would be the simpler idea yes however this method will return null if list a or list b is not sorted (removed from the code snippet). because of that sorting list c would be redundant – Paris Aug 27 '21 at 07:59

5 Answers5

1

Your index on the shorter array is exceed its maximum index. Need to check whether a Count is exceed the maximum index.

class Program {
  static List<int> Merge(List<int> list_a, List<int> list_b) {
    List<int> list_c = new List<int>();

    int countA = 0, countB = 0;

    for (int i = 0; i < list_a.Count + list_b.Count; i++) {
      if (countA < list_a.Count && countB < list_b.Count) {
        if (list_a[countA] <= list_b[countB]) {
          list_c.Add(list_a[countA]);
          countA++;
        }
        else {
          list_c.Add(list_b[countB]);
          countB++;
        }
      }
      else if (countA < list_a.Count) {
        list_c.Add(list_a[countA]);
        countA++;
      }
      else {
        list_c.Add(list_b[countB]);
        countB++;
      }

    }
    return list_c;
  }
  static void Main(string[] args) {
    List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
    List<int> myList2 = new List<int> { 4, 5, 6 };
    Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)) + "}");
  }
}
Rizquuula
  • 578
  • 5
  • 15
0

Considering you want to use cycles:

public static List<int> Merge(List<int> list_a, List<int> list_b)
{
    int firstListIndexer = 0, secondListIndexer = 0;    
    List<int> list_c = new List<int>();

    // Traverse lists, until one of them run out of the elements
    while (firstListIndexer < list_a.Count && secondListIndexer < list_b.Count)
    {
        
        if (list_a[firstListIndexer] < list_b[secondListIndexer])
            list_c.Add(list_a[firstListIndexer++]);
        else
            list_c.Add(list_b[secondListIndexer++]);
    }
 
    // Store remaining elements of first list
    while (firstListIndexer < list_a.Count)
        list_c.Add(list_a[firstListIndexer++]);
 
    // Store remaining elements of second list
    while (secondListIndexer < list_b.Count)
        list_c.Add(list_b[secondListIndexer++]);
    return list_c;
}

Also, you can read this to improve your knowledge on the subject.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
John Doe
  • 193
  • 1
  • 8
0

If we can assume that both lists are ascendingly ordered then you can merge the collections like this to respect ascending ordering.

static List<int> MergeTowAscendinglyOrderedCollections(IEnumerable<int> collectionA, IEnumerable<int> collectionB)
{
    var result = new List<int>();
    IEnumerator<int> iteratorA = collectionA.GetEnumerator();
    IEnumerator<int> iteratorB = collectionB.GetEnumerator();

    bool doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
    bool doesIteratorBHaveRemainingItem = iteratorB.MoveNext();

    void SaveIteratorAsCurrentAndAdvanceIt()
    {
        result.Add(iteratorA.Current);
        doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
    }

    void SaveIteratorBsCurrentAndAdvanceIt()
    {
        result.Add(iteratorB.Current);
        doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
    }

    do
    {
        if (iteratorA.Current < iteratorB.Current)
        {
            if (doesIteratorAHaveRemainingItem) SaveIteratorAsCurrentAndAdvanceIt(); 
            else SaveIteratorBsCurrentAndAdvanceIt();
        }
        else if (iteratorA.Current > iteratorB.Current)
        {
            if (doesIteratorBHaveRemainingItem) SaveIteratorBsCurrentAndAdvanceIt(); 
            else SaveIteratorAsCurrentAndAdvanceIt();
        }
        else if (iteratorA.Current == iteratorB.Current)
        {
            SaveIteratorAsCurrentAndAdvanceIt();
            SaveIteratorBsCurrentAndAdvanceIt();
        }

    } while (doesIteratorAHaveRemainingItem || doesIteratorBHaveRemainingItem);

    return result;
}

In case of duplication I've added both numbers to the merged list but depending your business requirements you can adjust the code to omit one or both values from the result.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
0

you can do a Union

List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};

var merged = myList1.Union(myList2).OrderBy(o=>o).ToList();

foreach(int number in merged)
Console.WriteLine(number);

output as follows

1 2 3 4 5 6 7 8 9

thanzeel
  • 431
  • 4
  • 12
0

If you have to implement your serlf:

Implementation with no counters and no indexes in just a few lines using Coroutines:

      class Program {
    
        static void Main() {

          List<int> l1 = new List<int>() { 9,8, 7, 5, 3, 1 };
          List<int> l2 = new List<int>() {12 ,10, 8, 6, 4, 2 };
          IEnumerable<int> res = MergeAscending(sl1, sl2);

          foreach (int item in res) {
            Console.Write($"{item},");
          }

          Console.Read();
        }
    
        static IEnumerable<T> MergeAscending<T>(IEnumerable<T> l1, IEnumerable<T> l2) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable {
    
           IEnumerator<T> e1 = l1.AsParallel().OrderBy(e => e).GetEnumerator();
           IEnumerator<T> e2 = l2.AsParallel().OrderBy(e => e).GetEnumerator();

           IEnumerator<T> longest; //to yield longest list remains

//First move needed to init first "Current"
          e1.MoveNext();
          e2.MoveNext();
    
//yields smaller current value and move its IEnumerable pointer
//breaks while loop if no more values in some Enumerable and mark the other one as longest

          while (true) {
            if (e1.Current.CompareTo(e2.Current) < 0) {
              yield return e1.Current;
              if (!e1.MoveNext()) { longest = e2; break; }
            }
            else {
              yield return e2.Current;
              if (!e2.MoveNext()) { longest = e1; break; }
            }
          }

    //finish the longest Enumerator
          do {
            yield return longest.Current;
          } while (longest.MoveNext());
    
        }
      }

Anyway, my recomendation is just as Siavash in the comments:

var merged = myList1.Union(myList2).AsParallel().OrderBy(e => e).ToList();
jlvaquero
  • 8,571
  • 1
  • 29
  • 45