0

In my code I have 2 arrays and I want to merge the both using right sequence. and save value to 3rd array. I tried a lot but could not find perfect solution.

public void Toolchange_T7()
{
    for (int T7 = 0; T7 < sModulename_listofsafetysensor.Length; T7++)
    {
        if (sModulename_listofsafetysensor[T7] != null && sModulename_listofsafetysensor[T7].Contains("IR") && sModulename_listofsafetysensor[T7].Contains("FS"))
        {
            sElement_toolchanger[iET7] = sModulename_listofsafetysensor[T7];
            iET7++;
        }

    }
    for (int T7 = 0; T7 < sDesignation_toolchanger_t7.Length; T7++)
    {
        if (sDesignation_toolchanger_t7[T7] != null && sDesignation_toolchanger_t7[T7].Contains("IR") && sDesignation_toolchanger_t7[T7].Contains("FW"))
        {
            sDesignation_toolchanger[iMT7] = sDesignation_toolchanger_t7[T7];
            iMT7++;
        }
    }
}

sElement_toolchanger contains:

++ST010+IR001+FW001 
++ST010+IR002+FW001
++ST010+IR006+FW001 

sDesignation_toolchanger contains:

++ST010+IR001.FS001
++ST010+IR001.FS002
++ST010+IR002.FS001
++ST010+IR002.FS002
++ST010+IR006.FS001
++ST010+IR006.FS002

My desired output is:

++ST010+IR001+FW001 
++ST010+IR001.FS001
++ST010+IR001.FS002
++ST010+IR002+FW001
++ST010+IR002.FS001
++ST010+IR002.FS002
++ST010+IR006+FW001 
++ST010+IR006.FS001
++ST010+IR006.FS002

It will be very helpful if some one know perfect solution

Xtros
  • 467
  • 5
  • 9
Piyush B
  • 45
  • 1
  • 5
  • 7
    This question would benefit from a description of what is currently going wrong (though kudos for providing sample input and output!) – BradleyDotNET Jan 29 '19 at 16:44
  • Can you explain What your code is currently doing? Have you looked at https://stackoverflow.com/questions/1547252/how-do-i-concatenate-two-arrays-in-c ? It seems that your collections are just string arrays and can be easily merged. – Glubus Jan 29 '19 at 16:48
  • I want to put output value in the right sequence and later i will fill this data in to word table....mearging 2 array is not big issuue but i want output in sequence form. – Piyush B Jan 29 '19 at 16:55
  • Your data sorts to the order you want, so just Sort or OrderBy. – Murray Foxcroft Jan 29 '19 at 16:56
  • for example as i wrote in output value description I want to take one value from 1st array and then go to 2nd array and then take 2 value(based on data availabe inside that array) from that array then again i go to 1st array and take 2nd value of that array and so on.... – Piyush B Jan 29 '19 at 16:59
  • When you say "by the right sequence", what does that mean ? Is it alphabetical order ? custom order based on something else ? It is impossible to answer you... The two given answers assume alphabetical order. – Martin Verjans Jan 29 '19 at 17:00
  • What does your sort (/comparison) function look like? Are your input arrays in sorted order? If so, then you can pre-allocated an array of the appropriate length and walk both arrays, picking off the lowest sort-order value and moving it to your new array. – Flydog57 Jan 29 '19 at 17:00
  • Can you explain me by giving short example..!! – Piyush B Jan 29 '19 at 17:01
  • yes my both input arrays are in shorted order... – Piyush B Jan 29 '19 at 17:02
  • by right sequence meance....it depends on ST value and IR value for example from first array it takes ST010+IR001+FW001 then loop goes to second arrray and search for same ST010 and IR001 and whatever value it finds which has same ST010 and IR001 will put into next index of ST010+IR001+FW001...hope you understand – Piyush B Jan 29 '19 at 17:11

5 Answers5

4
using System.Collections;

var mergedAndSorted = list1.Union(list2).OrderBy(o => o);
  • 1
    And add the `.ToList()` at the end if you want the `List` instead of `IEnumerable` – Franck Jan 29 '19 at 16:58
  • Would this match the desired output ?? "++ST010+IR001+FW001 followed by ++ST010+IR001.FS001". Would your output be same ? – Anu Viswan Jan 29 '19 at 17:04
  • The problem with this is that it concatenates two sorted input arrays, and then sorts them again. If there are enough entries in the inputs, then this can be a lot of wasted work. A "single pass through" solution may be more appropriate – Flydog57 Jan 29 '19 at 18:58
2

Simplest would be to:

Convert the arrays to lists:

var List1 = new List<string>(myArray1);
var List2 = new List<string>(myArray2);

Merge the two lists together:

List1.AddRange(List2);

and sort them.

List1.Sort();
Murray Foxcroft
  • 12,785
  • 7
  • 58
  • 86
1

According to what you said in the comments, here is a small function that will take one item from the first array, then two from the second array and so on to make a third one.

This code could be improved...

static void Main(string[] args)
{
    string[] t1 = new string[] { "a", "b", "c" };
    string[] t2 = new string[] { "a1", "a2", "b1", "b2", "c1", "c2" };
    List<string> merged = Merge(t1.ToList(), t2.ToList());
    foreach (string item in merged)
    {
        Console.WriteLine(item);
    }
    Console.ReadLine();
}

private static List<T> Merge<T>(List<T> first, List<T> second)
{
    List<T> ret = new List<T>();
    for (int indexFirst = 0, indexSecond = 0; 
        indexFirst < first.Count && indexSecond < second.Count; 
        indexFirst++, indexSecond+= 2)
    {
        ret.Add(first[indexFirst]);
        ret.Add(second[indexSecond]);
        ret.Add(second[indexSecond + 1]);
    }
    return ret;
}

An example here

Martin Verjans
  • 4,675
  • 1
  • 21
  • 48
0

From your given sample Output, it doesn't look to be alphabetically sorted. In that scenario, you would need to use a Custom Comparer along with your OrderBy Clause after taking the Union.

For example, (since your sorting algorithm is unknown, am assuming one here for showing the example)

var first = new[]{"++ST010+IR001+FW001","++ST010+IR002+FW001","++ST010+IR006+FW001"};
var second = new[]{"++ST010+IR001.FS001",
                                      "++ST010+IR001.FS002",
                                      "++ST010+IR002.FS001",
                                      "++ST010+IR002.FS002",
                                      "++ST010+IR006.FS001",
                                      "++ST010+IR006.FS002"};
var customComparer = new CustomComparer();
var result = first.Union(second).OrderBy(x=>x,customComparer);

Where your custom comparer is defined as

public class CustomComparer : IComparer<string>
{
    int IComparer<string>.Compare(string x, string y)
    {
        var items1 = x.ToCharArray();
        var items2 = y.ToCharArray();
        var temp = items1.Zip(items2,(a,b)=> new{Item1 = a, Item2=b});
        var difference = temp.FirstOrDefault(item=>item.Item1!=item.Item2);

        if(difference!=null)
        {
            if(difference.Item1=='.' && difference.Item2=='+')
                return 1;
            if(difference.Item1=='+' && difference.Item2=='.')
                return -1;
        }
        return string.Compare(x,y);
    }

    public int GetHashCode(string obj)
    {
        return obj.GetHashCode();
    }
}

Output

enter image description here

Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
0

Here's a solution if the two input arrays are already sorted. Since I suspect your comparison function is non-straightforward, I include a separate comparison function (not very efficient, but it will do). The comparison function splits the string into two (the alpha part and the numeric part) and then compares them so that the numeric part is more "important" in the sort.

Note that it doesn't do any sorting - it relies on the inputs being sorted. It just picks the lower valued item from the current position in one of the two arrays for transfer to the output array. The result is O(N).

The code makes a single pass through the two arrays (in one loop). When I run this, the output is AA00, AA01, AB01, AB02, AC02, AA03, AA04. I'm sure there are opportunities to make this code cleaner, I just popped it off. However, it should give you ideas to continue:

public class TwoArrays
{
    private string[] _array1 = {"AA01", "AB01", "AB02", "AC02"};
    private string[] _array2 = {"AA00", "AA03", "AA04"};

    public void TryItOut()
    {
        var result = ConcatenateSorted(_array1, _array2);
        var concatenated = string.Join(", ", result);
    }

    private int Compare(string a, string b)
    {
        if (a == b)
        {
            return 0;
        }

        string a1 = a.Substring(0, 2);
        string a2 = a.Substring(2, 2);
        string b1 = b.Substring(0, 2);
        string b2 = b.Substring(2, 2);
        return string.Compare(a2 + a1, b2 + b1);
    }

    private string[] ConcatenateSorted(string[] a, string[] b)
    {
        string[] ret = new string[a.Length + b.Length];
        int aIndex = 0, bIndex = 0, retIndex = 0;
        while (true)    //do this forever, until time to "break" and return
        {
            if (aIndex >= a.Length && bIndex >= b.Length)
            {
                return ret;
            }

            if (aIndex >= a.Length)
            {
                ret[retIndex++] = b[bIndex++];
                continue;
            }

            if (bIndex >= b.Length)
            {
                ret[retIndex++] = a[aIndex++];
                continue;
            }

            if (Compare(a[aIndex], b[bIndex]) > 0)
            {
                ret[retIndex++] = b[bIndex++];
            }
            else
            {
                ret[retIndex++] = a[aIndex++];
            }
        }
    }
}

To get it to work with your data, you need to change the input arrays and provide your own comparison function (which you could pass in as a delegate).

Flydog57
  • 6,851
  • 2
  • 17
  • 18