tags:

views:

59

answers:

1

I have a custom sort routine that works great, but I was curious about how I would convert it to use less code with LINQ or lambda. SortByGrade sorts a string value representing a grade ( K - 12 ) so that it returns: K, 1, 2, 3, 4, etc. instead of 1, 10, 2, etc

    /// <summary>
    /// Sorts a grade ( K - 12 ) numerically
    /// </summary>
    /// <remarks>A sort column is added and then sorted</remarks>
    /// <param name="table">table to sort</param>
    /// <param name="columnToSort">column to sort</param>
    /// <param name="sortDirection">enum of either asc or desc</param>
    /// <returns>Sorted data table</returns>
    public static DataTable SortByGrade(DataTable table, string columnToSort, SortDirection sortDirection)
    {
        string tmpSortColumn = "TempSortColumn";
        table.Columns.Add(tmpSortColumn, typeof(int));

        foreach (DataRow row in table.Rows)
        {
            row[tmpSortColumn] = ConvertGrade(row[columnToSort].ToString());
        }

        // sort on our need sort column
        table.DefaultView.Sort = String.Format("{0} {1}", tmpSortColumn, sortDirection.ToString());

        // return the sorted table
        return table.DefaultView.ToTable();
    }

and sort helper:

private static int ConvertGrade(string grade)
    {   
        int convertedGrade;
        switch(grade.ToUpper().Trim())
        {
            case "K":
                convertedGrade = 0;
                break;
            case "1":
                convertedGrade = 1;
                break;
            case "2":
                convertedGrade = 2;
                break;
            case "3":
                convertedGrade = 3;
                break;
            case "4":
                convertedGrade = 4;
                break;
            case "5":
                convertedGrade = 5;
                break;
            case "6":
                convertedGrade = 6;
                break;
            case "7":
                convertedGrade = 7;
                break;
            case "8":
                convertedGrade = 8;
                break;
            case "9":
                convertedGrade = 9;
                break;
            case "10":
                convertedGrade = 10;
                break;
            case "11":
                convertedGrade = 11;
                break;
            case "12":
                convertedGrade = 12;
                break;
            // TODO: Remove these cases when the data is cleaned up
            case "00":
            case "17":
                convertedGrade = 100;
                break;
            default:
                convertedGrade = 0;
                break;
        }
return convertedGrade;
    }

Thanks so much.

+2  A: 

You can use DataTableExtensions for the AsEnumerable and CopyToDataTable methods.

public static DataTable SortByGrade(DataTable table,
  string columnToSort, SortDirection sortDirection) 
{

  IEnumerable<DataRow> query = 
    from row in table.AsEnumerable()
    orderby ConvertGrade(row[columnToSort].ToString())
    select row;

  if (sortDirection == "DESC")
  {
    query = query.Reverse();
  }

  DataTable result = query.CopyToDataTable();
  return result;
}

and sort helper:

private static int ConvertGrade(string grade)  
{
  string g = grade.ToUpper().Trim();
  int convertedGrade =
    g == "K" ? 0 :
    g == "1" ? 1 :
    g == "2" ? 2 :
    g == "3" ? 3 :
    g == "4" ? 4 :
    g == "5" ? 5 :
    g == "6" ? 6 :
    g == "7" ? 7 :
    g == "8" ? 8 :
    g == "9" ? 9 :
    g == "10" ? 10 :
    g == "11" ? 11 :
    g == "12" ? 12 :
// TODO: Remove these cases when the data is cleaned up
    g == "00" ? 100 :  
    g == "17" ? 100 :
    0;  

  return convertedGrade;  
}
David B
I didn't know about the CopyToDataTable method. Nice.
subt13