5

We have a list containing names of countries. We need to find names of countries from list b/w two letters. Like names of all countries with name starting b/w A-G and so on. We create following linq query but its ugly.

var countryAG = from elements in countryList
where elements.StartsWith("A") || 
elements.StartsWith("B") || 
elements.StartsWith("C") || 
elements.StartsWith("D") || 
elements.StartsWith("E") || 
elements.StartsWith("F") || 
elements.StartsWith("G") || 
elements.StartsWith("H") 
select elements;

where countryList is created in C#

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

Any help or any other efficient way to accomplish above task?

Yahia
  • 69,653
  • 9
  • 115
  • 144
Malik
  • 347
  • 1
  • 11
  • 29

8 Answers8

11
var countryAG = from elements in countryList
                where elements[0] >= 'A' && elements[0] <= 'H'
                select elements;

Chars are just numbers really, thus you can compare them as such

svick
  • 236,525
  • 50
  • 385
  • 514
chrisaut
  • 1,076
  • 6
  • 17
3

I can't test it right now, but I would try

countryList.Where((s) => s[0] <= 'A' && s[0] >= 'G');
Nick Babcock
  • 6,111
  • 3
  • 27
  • 43
3

You could use a prefix list and then use the prefix list for comparison - this way you can easily use different prefix lists based on what range you are interested in:

 List<string> prefixList = new List<string>() { "A", "B", "C", "D", "E", "F", "G" };
 var countryAG = countryList.Where( x=> prefixList.Any( p => x.StartsWith(p)));
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • Thanks @Broken but it is same as my current approach. I am not interested in writing all English alphabets. – Malik Aug 27 '11 at 20:01
2

Try

char[] startingLetters = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
var countryAG = 
    from elements in countryList 
    where elements.IndexOfAny(startingLetters, 0, 1) == 0 
    select elements;

See here for information on IndexOfAny.

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Thanks @Yahia but it is same as my current approach. I am not interested in writing all English alphabets. – Malik Aug 27 '11 at 20:01
  • sorry to read that - you asked for a more efficient way... I would bet that the query from my answer runs faster than the one you are currently using and thus I suggested it... – Yahia Aug 27 '11 at 20:04
  • Sorry @Yahia. I ignore efficiency aspect as I was constructing on "making things simple" and ignore "efficient" part. Sorry again. Also, do we have any way of "making things simple and efficient". Scenario is simple, we have list of countries name and we have to divide them among A-G, I-P and Q-Z. I thought Linq is quick and easy. Your thoughts please. – Malik Aug 27 '11 at 20:25
1

Try use this code:

var start = "a";
var end = "g";
var regex = new Regex(string.Format("^[{0}-{1}]", start, end));
var result = list.Where(x => regex.Match(x.ToLowerInvariant()).Success);

'start' and 'end' are static as an example.

Dima
  • 6,721
  • 4
  • 24
  • 43
0

I have two extension functions:

public static IEnumerable<char> Range(char start, char end)
{
  return Enumerable.Range((int)start, (int)end - (int)start + 1).Select(i => (char)i);
}

which creates a range of characters, and

public static bool In(this string source, IEnumerable<string> collection)
{
  return collection.Contains(source);
}

which is just the inverse of Contains, mostly for readability.

Together I can do:

where elements[0].In(Range('a', 'f')))

toddmo
  • 20,682
  • 14
  • 97
  • 107
0
        List<string> mainList = new List<string>()
        {
           "A","B","DD","EE","F","G","EE","CC","DD","Q","R","CC"
        };

        List<string> searchList = new List<string>() { "DD", "EE", "CC" };

        var finalList = mainList.Where(x => searchList.Any(p => p == x)).ToList();
Md Shahriar
  • 2,072
  • 22
  • 11
-1

Two ways to filter list according to first letter of string:

  1. list = list.Where(x => x.WordText.ToUpper().StartsWith(Character));
  2. list = list.Where(x => Regex.IsMatch(x.WordText.ToUpper().Substring(0, 1), Character));
Hardeep Singh
  • 818
  • 9
  • 14