我花了一些时间试图找到答案,我很接近,但仍然卡住了。
想象一下,您有以下文件夹和文本文件..
C:\dupfiles
C:\dupfiles\tarts
C:\dupfiles\tarts\moretarts
C:\dupfiles\tarts\lindsay.txt
C:\dupfiles\paris.txt
C:\dupfiles\britney.txt
C:\dupfiles\tarts\moretarts\britney.txt
C:\dupfiles\tarts\moretarts\paris.txt
我正在尝试运行显示重复项的LINQ查询(paris.txt& britney.txt)。在SQL中,您可以通过group by和having子句来执行此操作。
这是我到目前为止的代码......
using System;
using System.IO;
using System.Linq;
class Program
{
public static void Main(string[] args)
{
String strPath = @"C:\dupfiles";
var filelist = from file in Directory.GetFiles(strPath, "*", SearchOption.AllDirectories)
select file
into files
select Path.GetFileName(files);
var duplicateNames = filelist.GroupBy(file => filelist)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
foreach (var f in duplicateNames)
{
Console.WriteLine(f);
}
Console.WriteLine("Press <enter> to continue");
Console.ReadLine();
}
}
我不完全理解代码是如何工作的,结果并不完全是我正在寻找的。
这是输出......
System.Linq.Enumerable+WhereSelectArrayIterator`2[System.String,System.String]
在示例代码中,f是一种... System.Linq.Enumerable.WhereSelectArrayIterator
我错过了一块拼图。谁能帮我?
答案 0 :(得分:3)
对于某些标准,例如易于维护和速度,LINQ不一定是最好的答案。
例如,您可以拥有Dictionary<string, List<string>>
,其中包含文件名和重复项的路径:
static Dictionary<string, List<string>> GetDupes2(string baseDir)
{
Dictionary<string, List<string>> files = new Dictionary<string, List<string>>();
foreach (string f in Directory.EnumerateFiles(baseDir, "*.*", SearchOption.AllDirectories))
{
var fName = Path.GetFileName(f);
if (files.ContainsKey(fName))
{
files[fName].Add(f);
}
else
{
files.Add(fName, new List<string> { f });
}
}
return files;
}
键是文件名,值是文件的完整路径名列表。只需使用files.Where(f => (f.Value.Count > 1))
即可获得重复项。
答案 1 :(得分:3)
其他答案都没问题。如果你想坚持查询语法,那么你可以这样:
var duplicateNames = from filePath in Directory.GetFiles(strPath, "*", SearchOption.AllDirectories)
group filePath by Path.GetFileName(filePath) into files
where files.Count() > 1
select files;
为了便于阅读,我个人会选择引入let
条款:
var duplicateNames = from filePath in Directory.GetFiles(strPath, "*", SearchOption.AllDirectories)
let filename = Path.GetFileName(filePath)
group filePath by filename into files
where files.Count() > 1
select files;
let
基本上是您在整个查询过程中可以访问的临时变量。
然后,您可以使用嵌套的foreach
打印这些项目,如Joshua Miller所示。
答案 2 :(得分:2)
修改强>
此答案还将写入所有重复项的完整文件路径。
var strPath = @"YourPath";
var dupeFiles = Directory.GetFiles(strPath , "*", SearchOption.AllDirectories)
.Select(fullPath => new
{
Name = Path.GetFileName(fullPath),
FullPath = fullPath
})
.GroupBy(file => file.Name)
.Where(fileGroup => fileGroup.Count() > 1);
foreach (var dupeGroup in dupeFiles)
{
Console.WriteLine(dupeGroup.Key);
foreach (var dupeFile in dupeGroup)
{
Console.WriteLine($" {dupeFile.FullPath}");
}
}
它通过使用anonymous type来实现这一点。
如上所述,这将导致输出显示重复文件的标题以及所有重复项的完整路径,类似于下面的示例输出。
dupe.txt
C:\Users\testUser\Desktop\Temp\dupe.txt
C:\Users\testUser\Desktop\Temp\tarts\dupe.txt
dupe2.txt
C:\Users\testUser\Desktop\Temp\dupe2.txt
C:\Users\testUser\Desktop\Temp\tarts\dupe2.txt
答案 3 :(得分:1)
此代码按组Key
过滤文件名,并选择包含文件名的string[] duplicitNames = Directory.GetFiles(strPath, "*", SearchOption.AllDirectories)
.Select(f => Path.GetFileName(f))
.GroupBy (f => f)
.Where (g => g.Count () > 1)
.Select (g => g.Key)
.ToArray();
。
IGrouping<TKey, TElement>
为了更好地理解,代码可以分为两部分,例如像这样g
接口表示具有公共密钥的对象的集合。 IEnumerable<IGrouping<string, string>> groupedFileNames = Directory.GetFiles(strPath, "*", SearchOption.AllDirectories)
.Select(f => Path.GetFileName(f))
.GroupBy (f => f);
string[] duplicitNames = groupedFileNames
.Where (g => g.Count () > 1)
.Select (g => g.Key)
.ToArray();
就是这样一个分组。 HTH
IEnumerable
注意:的
IGrouping的签名如下所示,您可以看到它Count
来自public interface IGrouping<out TKey, out TElement>
: IEnumerable<TElement>, IEnumerable
:
$messages = array();
try {
$opt_param = array(
'maxResults' => 100,
'labelIds' => 'INBOX'
);
$messagesResponse = $service->users_messages->listUsersMessages($userId, $opt_param);
$messages = $messagesResponse->getMessages();
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
if(!empty($messages)) {
foreach ($messages as $message) {
print 'Message with ID: ' . $message->getId() . '<br/>';
}
}
return $messages;
。