Подтвердить что ты не робот

Как определить переменные в LINQ?

Этот код:

string[] files = {"test.txt", 
    "test2.txt", 
    "notes.txt", 
    "notes.doc", 
    "data.xml", 
    "test.xml", 
    "test.html", 
    "notes.txt", 
    "test.as"};

files.ToList().ForEach(f => Console.WriteLine(
        f.Substring(
            f.IndexOf('.') + 1, 
            f.Length - f.IndexOf('.') - 1
            )
    ));

создает этот список:

txt
txt
txt
doc
xml
xml
html
txt
as

Есть ли способ сделать f.IndexOf('.') переменную, чтобы в более сложных запросах LINQ это определялось в одном месте?

4b9b3361

Ответ 1

Если вы использовали Linq, вы можете использовать ключевое слово let для определения встроенной переменной (код, размещенный в вопросе, фактически не использует Linq).

var ext = from file in files
          let idx = f.LastIndexOf('.') + 1
          select file.Substring(idx);

Однако для конкретного сценария, который вы опубликовали, я рекомендую использовать Path.GetExtension вместо того, чтобы самостоятельно разбирать строку (например, ваш код будет разбит, если в файле есть файл .).

var ext = from file in files select Path.GetExtension(file).TrimStart('.');
foreach (var e in ext)
{
    Console.WriteLine(e);
}

Ответ 2

Вы можете сделать это

files.ToList().ForEach(f => { var i = f.IndexOf('.'); 
   Console.WriteLine(f.Substring(i + 1, f.Length - i - 1));}
);

Ответ 3

Если вы не хотите использовать синтаксис типа from, вы можете сделать что-то подобное с методом Select:

var extensions = files
        .Select(x => new { Name = x, Dot = x.IndexOf('.') + 1 })
        .Select(x => x.Name.Substring(x.Dot));

Хотя, как и Грег, я бы рекомендовал использовать метод Path.GetExtension. И с методами, которые могут понравиться вот так:

var extensions = files
        .Select(x => Path.GetExtension(x));

И в этом случае я действительно думаю, что читать намного легче, чем предлагаемые выражения linq.


Чтобы записать его на консоль, вы можете сделать это:

extensions
    .ToList()
    .ForEach(Console.WriteLine);