views:

56

answers:

5

I guess this is probably going to be obvious in retrospect but I am finding it very hard to get my head round this.

Basically I just want to use LINQ to Objects to select from a range of objects with a surname property the surnames alphabetically between two surnames e.g. in the list:

Adams
Bentham
Bickford
Gillies
Kelly
Moore
Peters
Rutherford
Smith
Taylor
Williams

If you selected from "Kelly" to "Smith" it would return:

Kelly
Moore
Peters
Rutherford
Smith

inclusive.

It has to be specific enough that in the case where one were to select Kelly to Smith and there was a Kellerman before and a Smythe after the query would leave those out so LIKE 'K%' and LIKE 'S%' are no good. Besides you'd have to go through all the letters inbetween k and s to get there.

I am likely just being foolish in the way I'm putting the question to Google but no one else seems to have this alphabetic concern. Hope someone can help.

EDIT: So far so good folks. But here's a brainrtwister. We want to set a Maximum number of records returned.

e.g If we ask for Bickford to Rutheerford with a max of 3 we should get back:

Bickford
Gillies
Kelly

At present we just get three of the names between the goalposts at random.

Any ideas?

+3  A: 

I think you're looking for something like this

static IEnumerable<string> GetNames(IEnumerable<string> originalList, string fromName, string toName)
{
    foreach (string name in originalList)
    {
        if (name.CompareTo(fromName) >= 0 && name.CompareTo(toName) <= 0)
            yield return name;
    }
}

Or the LINQ version

static IEnumerable<string> GetNames(IEnumerable<string> originalList, string fromName, string toName)
{
    var query = from name in originalList
                where name.CompareTo(fromName) >= 0 && name.CompareTo(toName) <= 0
                select name;

    return query;
}

Example usage to product your Kelly to Smith inclusive list

string[] surnames = { "Adams", "Bentham", "Bickford", "Gillies", "Kelly", "Moore", "Peters", "Rutherford", "Smith", "Taylor", "Williams" };

foreach (string name in GetNames(surnames, "Kelly", "Smith"))
    Console.WriteLine(name);
Anthony Pegram
Broadly speaking this has done the job. Akthough it doesn't help me solve the second part of the problem which I'll probably stick up as a separate question later.
bert
A: 

I think this should do it:

var Names = SourceList.OrderBy(x => x.SurName).Select(x => x.SurName >= "Kelly")
            .Select(x => x.SurName <= "Smith").ToList();

I may be very wrong. Still new with all this.

Ian Jacobs
You may wish to use the Compare Method in Anthony's solution instead of mine in the Select clauses.
Ian Jacobs
A: 

what about something like

names
    .Where(n => n.surname.CompareTo(fromName) >= 0)
    .Where(n => n.surname.CompateTo(toName) <= 0)
Frank
A: 
    public IEnumerable<UserListItem> GetFilteredUsers(String start, String end)
    {
        var Users = from u in User.GetUsers()
                    let firstLetter = Char.ToUpper(u.FirstName[0])
                    let startLetter = Char.ToUpper(start[0])
                    let endLetter = Char.ToUpper(end[0])
                    where firstLetter >= startLetter && firstLetter <= endLetter
                    orderby u.FirstName
                    select u;
    }
decyclone
A: 

How about:

var results = Users
    .OrderBy(x => x.Surname)
    .SkipWhile(x => x.Surname.CompareTo("Kelly") < 0)
    .TakeWhile(x => x.Surname.CompareTo("Smith") <= 0);
richeym