0
votes

I would like to sort List, where last element of the string array is sort key. I need top 5 results.(with lower key)

This works, but I don't want to use LINQ:

    ...
    List<string[]> gameResults = OpenResults(fileLocation);
    gameResults.Add(CurrentPlayerResult());

    var newOrderedGameResults =
    from line in currentGameResults
    orderby int.Parse(line.LastOrDefault())
    select line;
    ...

But this don't:

    public void SaveResults(string fileLocation = @"..\..\GameResults.txt")
    {
        // string[] format:
        // [0],..,[n-1], [n]
        // names,        mistakeCount 
        List<string[]> gameResults = OpenResults(fileLocation);
        gameResults.Add(CurrentPlayerResult()); 

        QuickSort(gameResults, 0, gameResults.Count - 1);
        try
        {
            using (StreamWriter resultsFile = new StreamWriter(fileLocation))
            {
                foreach (var line in gameResults.Take(5))
                {
                    for (int i = 0; i < line.Length - 1; i++)
                    {
                        resultsFile.Write("{0} ", line[i]);
                    }
                    // dont add " " after last element
                    resultsFile.WriteLine("{0}", line[line.Length - 1]);
                }
            }
        }
        catch (IOException exception)
        {
            Console.WriteLine("The file could not be write:");
            Console.WriteLine(exception.Message);
        }

where:

    private void QuickSort(List<string[]> listToSort, int left, int right)
    {
        int pivot = left; //(left + right) / 2;
        int leftHold = left;
        int rightHold = right;

        while (left < right)
        {
            while (GetScoreFromLine(listToSort[right]) >= pivot && left < right)
            {
                right--;
            }
            if (left != right)
            {
                listToSort[left] = listToSort[right];
                left++;
            }

            while (GetScoreFromLine(listToSort[left]) <= pivot && left < right)
            {
                left++;
            }
            if (left != right)
            {
                listToSort[right] = listToSort[left];
                right--;
            }
        }
        listToSort[left] = listToSort[pivot];
        pivot = left;
        left = leftHold;
        right = rightHold;

        if (left < pivot)
        {
            QuickSort(listToSort, left, pivot - 1);
        }
        if (right > pivot)
        {
            QuickSort(listToSort, pivot + 1, right);
        }
    }

And:

    private int GetScoreFromLine(string[] lineToParce)
    {
        int length = lineToParce.Length;
        return int.Parse(lineToParce[length - 1]);
    }

Dont work, correctly.

Is there way to use ARRAY.SORT? Can anyone help. Thanks.

2
Would you perhaps consider reducing this to the minimum necessary code to duplicate the issue? Considering we're talking about a List<string[]> sort without using LINQ I would imagine that's not so hard.yamen
Why wouldn't you want to use LINQ and why can't you use the regular .Net sorting methods?Wesley Wiser
Wesley Wiser, i dont know how to implement .net sort to list<string[]>. If u can send Links to examples, it would help. Its void, and sort works fine if listToSort is int and GetScoreFromLine(listToSort[left/right]) is just a number.Martin Kostov
@yamen Because it’s sorting in place.Konrad Rudolph
I sure dont understand, why you would actively try to stay away from such beauty as gameResults.OrderBy(x => int.Parse(x[x.Length - 1]))Frank

2 Answers

3
votes

You use List so you can also use List.Sort I guess. With a comparer delegate or if you insist also with a comparer class.

List<string[]> lists = new List<string[]>
{
     new string[] { "1", "b", "5"},
     new string[] { "2", "b", "3"},
     new string[] { "3", "b", "1"},
     new string[] { "4", "b", "2"},
};
lists.Sort((a, b) => int.Parse(a[a.Length - 1]) - int.Parse(b[b.Length - 1]));

I am not sure why you specifically ask for Array.Sort when you show an example with a List. Anyway if you need to you can use List.ToArray() and then use

var arr = lists.ToArray();
Array.Sort(arr, (a, b) => int.Parse(a[a.Length - 1]) - int.Parse(b[b.Length - 1]));

This one is nearly the same and shows nicely how consistent the .NET Framework did evolve over the years when Generics were added to the CLR back in 2005 with .NET 2.0.

0
votes

The following should work for what you need:

public void SaveResults(string fileLocation = @"..\..\GameResults.txt")
{
    // string[] format:
    // [0],..,[n-1], [n]
    // names,        mistakeCount 
    List<string[]> gameResults = OpenResults(fileLocation);
    gameResults.Add(CurrentPlayerResult()); 
    gameResults.Sort(CompareResults);
    ...
}

private int CompareResults(string[] left, string[] right)
{
    if ((left == null && right == null) || (left.Length == 0 && right.Length == 0))
        return 0;
    else if (left == null || left.Length == 0)
        return 1;
    else if (right == null || right.Length == 0)
        return -1;

    int leftVal = int.Parse(left[left.Length - 1]);
    int rightVal = int.Parse(right[right.Length - 1]);

    return leftVal.CompareTo(rightVal);
}