2
string[] userInputs= {  "a","c","b"}
DataRow[] datarows=//datarows contains values like "A","B","C","D","E" 
List<DataRow> data = datarows.CopyToDataTable().AsEnumerable().ToList();

 IEnumerable<DataRow> orderedData = data.OrderByDescending(item => Array.IndexOf(userInputs, item.Field<string>(columnName)));

//My datarows contains all values in uppercase but if user gives inputs in Lowercase ,then it is not working linq-orderby-against-specific-values

Edit : I cant force the User to give inputs in Lower/Upper and even my DataRow will also contain data in Both lower /upper. The query should work irrespective of the case.

Community
  • 1
  • 1
Kiran Malgi
  • 97
  • 1
  • 1
  • 6

2 Answers2

3

if your datarow is already in upper case, then just force user input to be in upper case too.

string[] userInputs= {  "a","c","b"}.Select(x => x.ToUpperInvariant())
                                    .ToArray();
bto.rdz
  • 6,636
  • 4
  • 35
  • 52
  • 1
    Using `ToUpper()` is not culture-safe and is almost never the right way to do case-insensitive comparisons, and any time it _is_ used or (especially) recommended to others, should always come with that caveat. – Peter Duniho Nov 30 '15 at 07:06
  • how about `ToUpperInvariant()`? – bto.rdz Nov 30 '15 at 15:27
  • `ToUpperInvariant()` makes you unsafe in a predictable way, but it's still not culture-safe (i.e. doesn't provide an equality comparison in a culturally-appropriate way). Note: I'm not against using shortcuts like `ToUpper()`/`ToLower()` and invariant versions for comparisons in contexts where one is certain that culture settings won't be an issue; but it must be done with full awareness of the implications/trade-offs. IMHO, a good answer proposing to use these will describe those implications and trade-offs so that people who might use it are made aware of the techniques risks and limitations – Peter Duniho Nov 30 '15 at 17:32
3

It is best to use culture-safe comparisons when dealing with text. Even if you think right now your code will never be localized or use input data from other cultures, it's better to be in the habit of doing the code right.

In this scenario, that means using one of the case-insensitive comparers from StringComparer. For example:

string[] userInputs= {  "a","c","b"};
DataRow[] datarows=//datarows contains values like "A","B","C","D","E" 
List<DataRow> data = datarows.CopyToDataTable().AsEnumerable().ToList();
StringComparer comparer = StringComparer.CurrentCultureIgnoreCase;

IEnumerable<DataRow> orderedData = datarows
    .OrderByDescending(item => Array.FindIndex(
        userInputs, input => comparer.Equals(input, item.Field<string>(columnName))));

Note: for some reason, your original code example uses OrderByDescending(), and I have duplicated that usage in my example above. But of course, that will obviously cause the data rows order to actually be the reverse of the original order in userInputs.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136