我不确定我找到的解决这个问题的方法是否正确。
示例场景:
class FolderItem
{
public int Id { get; set; }
public string Name { get; set; }
public FileItem[] Files { get; set; }
}
class FileItem
{
public int Id { get; set; }
public int FolderId { get; set; }
public string Name { get; set; }
public byte[] Content { get; set; }
}
从2个收藏开始:
FolderItem[] folders =
new FolderItem[]
{
new FolderItem
{
Id = 1,
Name = "Folder1"
},
new FolderItem
{
Id = 2,
Name = "Folder2"
}
};
FileItem[] files =
new FileItem[]
{
new FileItem
{
Id = 100,
FolderId = 1,
Name = "file1.txt",
Content = new byte[] { 1, 2, 3 }
},
new FileItem
{
Id = 200,
FolderId = 1,
Name = "file2.txt",
Content = new byte[] { 1, 2, 3 }
},
new FileItem
{
Id = 300,
FolderId = 2,
Name = "file3.txt",
Content = new byte[] { 1, 2, 3 }
},
new FileItem
{
Id = 400,
FolderId = 2,
Name = "file4.txt",
Content = new byte[] { 1, 2, 3 }
}
};
为了将“ FileItem”放入“文件夹”的属性“文件”中,我这样做:
files
.Join
(
folders,
x => x.FolderId,
x => x.Id,
(x,y) => new { File = x, Folder = y }
)
.GroupBy(x => x.Folder.Id)
.Select
(x =>
{
var folder = x.First().Folder;
folder.Files = x.Select(z => z.File).ToArray();
return folder;
}
)
我可以在.First()
lambda中使用GroupBy
,因为我正在按其ID分组
我得到:
是否有一些扩展方法可以比此方法更快或更好?有什么最佳做法吗?
答案 0 :(得分:1)
只需使用Where
创建一个新列表即可获取每个文件夹的文件。
var foldersWithFiles = folders
.Select
(
folder =>
new FolderItem
{
Id = folder.Id,
Name = folder.Name,
Files = files.Where
(
file => file.FolderId = folder.Id
).ToArray()
)
);
您以后总是可以替换旧列表,如下所示:
folders = foldersWithFiles.ToArray();
答案 1 :(得分:1)
您可以简单地循环播放文件夹并将项目添加到它们各自的文件夹中。
首先,您需要在各处将FileItem[]
更改为List<FileItem>
,将FolderItem[]
更改为List<FolderItem>
。
您需要像这样的List
的删除并获取扩展方法。优化此功能可删除元素,同时仍返回它们,从而减少数量
后续迭代。
public static List<T> RemoveAndGet<T>(this List<T> list, Func<T, bool> predicate)
{
var itemsRemoved = new List<T>();
// iterate backward for performance
for (int i = list.Count - 1; i >= 0; i--)
{
// keep item pointer
var item = list[i];
// if the item match the remove predicate
if (predicate(item))
{
// add the item to the returned list
itemsRemoved.Add(item);
// remove the item from the source list
list.RemoveAt(i);
}
}
return itemsRemoved;
}
然后,您唯一的查询就是用此查询填充当前的文件夹。
folders.ForEach(folder =>
folder.Files.AddRange(files.RemoveAndGet(file => file.FolderId == folder.Id)));