2

It need to sort a string array like this to a special format. Our Array is:

input1 = new string[12]{"Active1","12","mm","Active2","17","mm","Width","25","mil","Height","20","mil"}  

and our desired sort list is:

sort = new string[6]{"Serial","Width","Height","Active1","Active2","Time"}  

My valid format for output is this:

Output = [{Serial,null,null},{Width,25,mil},{Height,20,mil},{Active1,12,mm},{Active2,17,mm},{Time,null,null}]

It is necessary to set null value for data that don't exist in Input Array.

I'm using this code for my purpose:

var Output = (from i in Enumerable.Range(0, input.Length / 3)
                       let index = Array.IndexOf(sort, input[i * 3])
                       where index >= 0
                       select ne3w string[] { input[i * 3], input[i * 3 + 1] , input[i * 3 + 2]})
                       .OrderBy(a => Array.IndexOf(sort, a[0])).ToArray();

but it doesn't show the values that don't exist in input Array.

2
  • 4
    I dont think this operation is called SORT Commented Jul 12, 2015 at 3:35
  • @captainsac you can call whatever you want Commented Jul 12, 2015 at 3:39

5 Answers 5

4

I would put this into a separate method:

private static IEnumerable<string[]> TransformInput(string[] input)
{
    return from key in new[] { "Serial", "Width", "Height", "Active1", "Active2", "Time" }
           let keyIndex = Array.IndexOf(input, key)
           let hasData = keyIndex > 1
           select new[]
           {
               key,
               hasData ? input[keyIndex + 1] : null,
               hasData ? input[keyIndex + 2] : null
           };
}

And then use it as follows:

var input1 = new string[12]   
{ "Active1", "12", "mm", "Active2", "17", "mm", "Width", "25", "mil", "Height", "20", "mil" };

var sorted = TransformInput(input1);
Sign up to request clarification or add additional context in comments.

2 Comments

something is wrong when we use this code. It said can not convert to string[]
See my edit, can you paste your code if you're still having issues.
1

You can do it with the method below:

    private string[][] Sort(string[] input)
    {

        List<string> inputList = new List<string> ();
        inputList = input.ToList<string> ();

        List<string[]> sortedList = new List<string[]> ();

        string[] sort = new string[]{"Serial", "Width", "Height", "Active1", "Active2", "Time"};

        foreach(string key in sort)
        {
            if (inputList.Contains<string> (key)) {
                int i = inputList.IndexOf (key);
                string[] t = new string[]{inputList[i],inputList[i+1],inputList[i+2]};
                sortedList.Add (t);
            }
            else
            {
                string[] t = new string[]{key,null, null};
                sortedList.Add (t);
            }
        }

        return sortedList.ToArray<string[]> ();
    }

Hope it help you out!

Comments

1

Given the two sets of input data:

var input1 = new string[12]
{
    "Active1","12","mm",
    "Active2","17","mm",
    "Width","25","mil",
    "Height","20","mil"
};

var sort = new string[6]
{
    "Serial","Width","Height","Active1","Active2","Time"
};

This worked for me:

var lookup =
    input1
        .Select((x, n) => new { x, n })
        .ToLookup(xn => xn.n / 3)
        .ToLookup(
            z => z.ElementAt(0).x,
            z => z.Skip(1).Select(w => w.x));

var result =
    sort
        .Select(x =>
            new [] { x }
                .Concat(lookup[x].SelectMany(z => z))
                .Concat(new string[] { null, null })
                .Take(3)
                .ToArray())
        .ToArray();

I got this result:

result

Comments

1

Building on Nitesh, but removing the need to scan input repeatedly by using a dictionary

using System.Linq; //at top of file

private static string[][] TransformInput(string[] input)
{
    var sortOrder = new[] { "Serial", "Width", "Height", "Active1", "Active2", "Time" };

    //dictionary pointing words to position in input
    var inputDict = Enumerable.Range(0, input.Length/3)
            .Select(i => i*3).ToDictionary(i => input[i]);
    //Try to read position from dictionary; return nulls if fail
    return sortOrder.Select(x => {
            int i;
            return (inputDict.TryGetValue(x, out i))
                ? new[]{x, input[i+1], input[i+2]}
                : new[]{x, null, null};
        }).ToArray();
}

2 Comments

I think the code have some mistake. Enumerable is not a variable. Also a string[] doesn't contain a definition for select
Thanks. I fixed the code and added the dependency for System.Linq
1

I think this code is good for your problem.

 static List<string[]> SortedList(string[] input)
    {
        var sort = new string[6] { "Serial", "Width", "Height", "Active1", "Active2", "Time" };
        List<string[]> output = new List<string[]>();
        for (int i = 0; i < sort.Length; i++)
        {
            var findIndex = input.ToList().IndexOf(sort[i]);
            if (findIndex != -1)
                output.Add(new string[3]
                    {
                        input[findIndex],
                        input[findIndex + 1],
                        input[findIndex + 2]
                    });
            else
                output.Add(new string[3]
                {
                    sort[i],
                    null,
                    null
                });
        }
        return output;
    }

And now you call that method:

 var input = new string[12] { "Active1", "12", "mm", "Active2", "17", "mm", "Width", "25", "mil", "Height", "20", "mil" };
 var output = SortedList(input);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.