0

试图在一组文件中获取不同标识符的集合。这个 Lambda 查询我做错了什么:

   var enumDir = Directory.GetFiles(folder);
   var distinctCode = enumDir.Select(s => Path.GetFileName(s).Substring(8, 4))
                              .GroupBy(s => s.ToString());

提前致谢 ...

编辑

@empi 建议。我希望从文件名中得到一个不同的 4 个字母子字符串的列表,我得到的是什么,或者我已经将 Path.Get....例外。

@Oskar Kjellin 建议我应该提到每个文件名的长度设置为 45 个字符

最终解决方案 | 感谢 empi 和奥斯卡

var enumDir = Directory.GetFiles(folder).Where(a => Path.GetFileName(a).Length > 12);
var distinctCode = enumDir.Select(s => Path.GetFileName(s).Substring(8, 4)).Distinct();

真的是这两种建议的结合,我不知道该为谁标记答案。

4

4 回答 4

1

您应该始终在调用子字符串之前检查长度以避免异常......

 enumDir = Directory.GetFiles(folder);
 distinctCode = enumDir.Select(s => Path.GetFileName(s))
.Select( s=> s.Length >= 12 ? s.Substring(8, 4) : s).GroupBy(s => s);

您永远无法真正控制文件夹中的文件。例如,windows 可以创建 thumbs.db,它是图像或其他临时文件缩略图的缓存。

也许您只想过滤掉具有固定长度的那些:

 enumDir = Directory.GetFiles(folder);
 distinctCode = enumDir.Select(s => Path.GetFileName(s)).Where(s=>s.Length == 45)
.Select( s=> s.Substring(8, 4)).GroupBy(s => s);
于 2012-04-28T19:20:26.873 回答
1

enumDir.Select(s => Path.GetFileName(s).Substring(8, 4))- 此代码应返回IEnumerable<string>- 检查此集合是否正常。如果没问题,那么只需使用Distinct().

于 2012-04-28T19:24:21.147 回答
1

我怀疑您要查找的是获取实际文件名,但按子字符串对它们进行分组。

var result = Directory.GetFiles(folder)
    .Select(s => Path.GetFileName(s))
    .Where(s => s.Length > 12)
    .GroupBy(s => s.Substring(8, 4));

现在,result您拥有Key作为子字符串的组对象,如果枚举它们,您将获得与该键匹配的实际文件名。

于 2012-04-28T19:34:08.867 回答
1

我认为使用正则表达式进行验证可以做得更好。您尝试在查询中执行的检查类型过于复杂,无法在单个查询中执行。该目录中可能有其他文件不符合您的模式,这是您不期望的,并且可能会搞砸一切。这种复杂性可以通过正则表达式来捕获。如果您的文件名遵循某种模式,一个简单的正则表达式匹配可以为您处理。

我不知道您的文件名是什么样的,所以我将使用 Windows Media Center 录制的电视作为示例。所有 WMC 文件名都有特定的模式:

[title]_[station]_[year]_[month]_[day]_[hour]_[minute]_[second].wtv

然后按标题对所有视频进行分组,您可以这样做:

var dir = @"C:\Users\Public\Recorded TV";
var wmcFileRe = new Regex(@"
    ^
    (?<title>.+)
    _
    (?<station>.+)
    _
    (?<date>\d{4}_\d{2}_\d{2})
    _
    (?<time>\d{2}_\d{2}_\d{2})
    \.wtv
    $
", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
var query =
    from filePath in Directory.EnumerateFiles(dir)
    let fileName = Path.GetFileName(filePath)
    let match = wmcFileRe.Match(fileName)
    where match.Success
    orderby match.Groups["title"].Value,
            match.Groups["date"].Value descending,
            match.Groups["time"].Value descending
    group filePath by match.Groups["title"].Value;

产生这样的东西:

例子

此外,使用Directory.EnumerateFiles()而不是Directory.GetFiles()这样您就不会预先创建该结果数组,该数组在其他任何地方都不需要。

于 2012-04-28T21:33:46.583 回答