Как определить переменные в 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 это определялось в одном месте?
Ответы
Ответ 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);