简体   繁体   English

C#LINQ语句

[英]C# LINQ statement

I have two lists; 我有两个清单。 List<int> numList has identifier number as its elements, and List<string> filePaths has path to file that needs to be analyzed as its elements. List<int> numList具有标识号作为其元素,而List<string> filePaths具有指向文件的路径,该文件需要作为其元素进行分析。 I want to filter filePaths based on the numList ; 我想基于numList过滤filePaths ; that is, I only want to select the filePaths whose file names have the identifier number that is present in the numList . 也就是说,我只想选择文件名具有numList存在的标识符号的numList

For example, filePaths has 例如, filePaths具有

C:/test/1.test.xlsx
C:/test/2.test.xlsx
C:/test/3.test.xlsx
C:/test/4.test.xlsx

and, numList has 并且, numList

1
2

In this case, I want to construct LINQ statement to only get 在这种情况下,我想构造LINQ语句以仅获取

C:/test/1.test.xlsx
C:/test/2.test.xlsx

I tried 我试过了

for(int i = 0; i < numList.Count; i++)
{
    filePaths = filePaths.Where(f => Convert.ToInt32(GetNumberFromString(Path.GetFileName(f))) == numList[i]).ToList();
}

And this is GetNumberFromString Helper Method 这是GetNumberFromString Helper方法

// Find number in the string
private string GetNumberFromString(string value)
{
    int number;

    string resultString = Regex.Match(value, @"\d+").Value;

    if (Int32.TryParse(resultString, out number))
    {
        return resultString;
    }
    else
    {
        throw new Exception(String.Format("No number present in the file {0}", value));
    }
}

I think this will work, but is there more elegant/efficient way of achieving this? 我认为这会起作用,但是是否有更优雅/更有效的方法来实现这一目标?

您可以使用单线执行此操作:

var filteredFilePaths = filePaths.Where(x => numList.Contains(GetNumberFromString(x));

I'd do it like this. 我会这样 The test method assumes that all the files in directory have appropriately formatted names. 该测试方法假定directory中的所有文件都具有适当格式的名称。 If that's not a reasonable assumption, it's easy enough to fix. 如果这不是一个合理的假设,则很容易修复。

This is overkill, however, if you only ever care about the "file number" in one place. 但是,如果您只关心一个地方的“文件号”,那就太过分了。

public class TestClass
{
    public static void TestMethod(String directory)
    {
        var files = System.IO.Directory.GetFiles(directory).Select(f => new FileInfo(f)).ToList();

        var numList = new[] { 1, 2 };

        var oneAndTwo = files.Where(fi => numList.Contains(fi.FileNumber)).ToList();
    }
}

public class FileInfo
{
    public FileInfo()
    {
    }
    public FileInfo(String path)
    {
        Path = path;
    }

    public int FileNumber { get; private set; }
    private string _path;
    public String Path
    {
        get { return _path; }
        set
        {
            _path = value;
            FileNumber = GetNumberFromFileName(_path);
        }
    }

    public static int GetNumberFromFileName(string path)
    {
        int number;

        var fileName = System.IO.Path.GetFileName(path);

        string resultString = Regex.Match(fileName, @"\d+").Value;

        if (Int32.TryParse(resultString, out number))
        {
            return number;
        }
        else
        {
            throw new Exception(String.Format("No number present in the file {0}", path ?? "(null)"));
        }
    }
}

A stand-alone One-liner using a Join : 使用Join的独立One-liner:

var result = filePaths.Select(x => new { Filename = Path.GetFileName(x), x })
    .Join(numList, x => Regex.Match(x.Filename, "^([0-9]+)").Value,
                   y => y.ToString(), 
                   (x, y) => x.x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM