2

Are there any Linq expression exists that gives a predicated list from end of the source list.

i.e: "abc1zxc".ToCharArray().SomeMagicLinq(p=>Char.IsLetter(p));

should give "zxc"

eakgul
  • 3,658
  • 21
  • 33

1 Answers1

1

You could use this approach:

var lastLetters = "abc1zxc".Reverse().TakeWhile(Char.IsLetter).Reverse();
string lastLettersString = new String(lastLetters.ToArray());

Not the most efficient way but working and readable.

If you really need it as a single (optimized) method you could use this:

public static IEnumerable<TSource> GetLastPart<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
 {
    var buffer = source as IList<TSource> ?? source.ToList();
    var reverseList = new List<TSource>();
    for (int i = buffer.Count - 1; i >= 0; i--)
    {
        if (!predicate(buffer[i])) break;
        reverseList.Add(buffer[i]);
    }
    for (int i = reverseList.Count - 1; i >= 0; i--)
    {
        yield return reverseList[i];
    }
}

Then it's more concise:

string lastLetters = new String("abc1zxc".GetLastPart(Char.IsLetter).ToArray());
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • That works, but uses 3 Linq expression. I asked to do it in one :( – eakgul Sep 22 '16 at 13:53
  • @Kowalski: it doesn't use 3 [query expressions](https://msdn.microsoft.com/en-us/library/bb397676.aspx) but one. It uses three LINQ methods but there is only one expression(the first line). But you are free to create a new method that does this all in one call. – Tim Schmelter Sep 22 '16 at 13:54
  • @Kowalski. added a one method approach – Tim Schmelter Sep 22 '16 at 14:06