4

I would like to convert the below "foreach" statement to a LINQ query that returns a substring of the file name into a list:

IList<string> fileNameSubstringValues = new List<string>();

//Find all assemblies with mapping files.
ICollection<FileInfo> files = codeToGetFileListGoesHere;

//Parse the file name to get the assembly name.
foreach (FileInfo file in files)
{
    string fileName = file.Name.Substring(0, file.Name.Length - (file.Name.Length - file.Name.IndexOf(".config.xml")));
    fileNameSubstringValues.Add(fileName);
}

The end result would be something similar to the following:

IList<string> fileNameSubstringValues = files.LINQ-QUERY-HERE;
1
  • 2
    There's no query here, just a transformation from A[] to B[]. Commented Jan 6, 2009 at 21:24

4 Answers 4

6

Try something like this:

var fileList = files.Select(file =>
                            file.Name.Substring(0, file.Name.Length -
                            (file.Name.Length - file.Name.IndexOf(".config.xml"))))
                     .ToList();
Sign up to request clarification or add additional context in comments.

3 Comments

Voted up: I prefer the extension method syntax to the query syntax here, since there's really no query: your goal is to perform a transform on all the elements. There's no 'where' or 'orderby' or a crossing 'select' even 'select new { x, y }.
@Jay, I also prefer the extension method syntax for simple projections, the query syntax I think I only use it when doing joins...
better because 1) fluent interface 2) no brackets around the query needed
2
IList<string> fileNameSubstringValues =
  (
    from 
      file in codeToGetFileListGoesHere
    select 
      file.Name.
        Substring(0, file.Name.Length - 
          (file.Name.Length - file.Name.IndexOf(".config.xml"))).ToList();

Enjoy =)

Comments

2

If you happen to know the type of the collection of FileInfos, and it's a List<FileInfo>, I'd probably skip the Linq and write:

        files.ConvertAll(
            file => file.Name.Substring(0, file.Name.Length - (file.Name.Length - file.Name.IndexOf(".config.xml")))
            );

or if it's an array:

        Array.ConvertAll(
            files,
            file => file.Name.Substring(0, file.Name.Length - (file.Name.Length - file.Name.IndexOf(".config.xml")))
            );

Mainly because I like saying "Convert" instead of "Select" to express my intent to a programmer reading this code.

However, Linq is part of C# now, so I think it's perfectly reasonable to insist that a reading programmer understand what Select does. And the Linq approach lets you easily migrate to PLinq in the future.

Comments

1

FYI,

file.Name.Substring(0, file.Name.Length - (file.Name.Length - file.Name.IndexOf(".config.xml")))

is the same as

file.Name.Substring(0, file.Name.IndexOf(".config.xml"));

Also, if that string ".config.xml" appears before the end of the file name, your code will probably return the wrong thing; You should probably change IndexOf to LastIndexOf and check that the index position returned + 11 (the size of the string) == length of the filename (assuming you're looking for files ending in .config.xml and not just files with .config.xml appearing somewhere in the name).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.