{...">

Move items in the array of strings to the left to fill the "holes"

I have a list of names and phones like:

var phonelist = List<string[]> 
{
     new string[] {"Bill", "1234", "12345", "12314" },
     new string[] {"Bob", "", "12345", "12314" },
     new string[] {"Chris", "", "", "12314" },
     new string[] {"Dave", "1234", "", "12314" },
     new string[] {"Andy", "1234", "12345", "" },
}

What is the most efficient / elegant way to process this list so that the "empty" numbers are filled on the right?

Note that arrays must be the same length, for example:

var phonelist = List<string[]> 
{
     new string[] {"Bill", "1234", "12345", "12314" },
     new string[] {"Bob", "12345", "12314", "" },
     new string[] {"Chris", "12314", "", "" },
     new string[] {"Dave", "1234", "12314", "" },
     new string[] {"Andy", "1234", "12345", "" },
}
+3
source share
7 answers

for each cell of the array, check if it was empty and replaced with cell + 1, if it is still empty, replace it with cell + 2 .. when the cell becomes empty, do the same with cell + 2 ...

    int j;

    foreach (string[] strs in phoneList)
    {
        for (int i = 0; i < strs.Length; i++)
        {
            j = 1;
            while (string.IsNullOrEmpty(strs[i]) && j < strs.Length - i)
            {
                if (!string.IsNullOrEmpty(strs[i + j])) // to not swap 2 empty strings
                {
                    strs[i] = strs[i + j];
                    strs[i + j] = "";
                }
                j++;
            }
        }
    }
+2
source

public static void PutEmptyStringsToTheEnd(string[] array) {
    int j = 0;
    for (int i = 0; i < array.Length; ++i)
        if (array[i].Length > 0)
            array[j++] = array[i];
    while (j < array.Length)
        array[j++] = "";
}

Call this function for each item in the list.

+2
source

- :

Comparison<string> comparison = (x,y) =>
{
    if (String.IsNullOrEmpty(x))
        return 1;
    if (String.IsNullOrEmpty(y))
        return -1;
    return String.Compare(x,y);
}

foreach (string[] array in phoneList)
{
    Array.Sort(array, comparison);
}

,


EDIT: since the name is always the first element, another option is to exclude it from sorting. No Array.Sortoverload accepts Comparison<T>and range, so instead you should use IComparer<T>:

class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (String.IsNullOrEmpty(x))
            return 1;
        if (String.IsNullOrEmpty(y))
            return -1;
        return String.Compare(x,y);
    }
}


foreach (string[] array in phonelist)
{
    Array.Sort(array, 1, array.Length - 1, new MyComparer());
}
+1
source

That should work. I donโ€™t know what was in C #, but the idea is there

foreach(string[] person in phonelist)
{
 string[] newPerson = {"","","",""};
 int index = 0;
 for(int i=0; i<4; i++)
 {
  if(!String.IsNullOrEmpty(person[i])) newPerson[index++] = person[i];
 }
 person = newPerson;
}
+1
source

simple and ugly: (

    for(var x=0;x<phonelist.Count;x++)
    {
        var strings = phonelist[x];

        var l = strings.Length;
        var newAr=new string[l];
        var k = 0;

        for (var i = 0; i < l; )
        {
            if(strings[i]!="")
            {
                newAr[k++] = strings[i];
            }
            i++;
        }

        for (; k < l; k++)
            newAr[k] = "";

        phonelist[x] = newAr;
    }
+1
source
List<string[]> sorted = new List<string[]>();

foreach (string[] entry in phoneList)
{
    List<string> nonEmpty = (from s in entry
                         where String.IsNullOrEmpty(s) == false
                         select s).ToList();

    int pad = entry.Length - nonEmpty.Count;

    List<string> pads = new List<string>();

    while (pad > 0)
    {
        pads.Add(String.Empty);
        --pad;
    }

    List<string> sortedEntry = new List<string>();
    sortedEntry.AddRange(nonEmpty);
    sortedEntry.AddRange(pads);

    sorted.Add(sortedEntry.ToArray());
}
0
source

This is a cooler

List<string[]> result = phonelist.Select(per => per.OrderBy(txt=>txt.Length==0).ToArray()).ToList();
0
source

Source: https://habr.com/ru/post/1716766/


All Articles