我已经有一个目录路径列表。例如:
/home/aar/las
/home/aar/las/pes
/home/aar/las/fmp
/home/aar/.thumbnails
/home/aar/.thumbnails/normal
/home/aar/yfolder
/home/aar/.kde
/home/aar/.kde/share
/home/aar/.kde/share/config
/home/aar/.kde/share/apps
/home/aar/.kde/share/apps/okular
我想删除所有子目录并仅保留父项。
为此,我使用了这个代码可以正常工作:
QStringList RemoveSubFolders_KeepParentFolders(QStringList FoldersList)
{
QStringList FoldersList_First = FoldersList;
QStringList FoldersList_Second = FoldersList;
QStringList ToDelete;
foreach (QString TheFolder_First, FoldersList_First) {
foreach (QString TheFolder_Second, FoldersList_Second) {
if (TheFolder_Second.startsWith(TheFolder_First) && TheFolder_First.toLower() != TheFolder_Second.toLower())
ToDelete.append(TheFolder_Second);
}
}
QStringListIterator i(ToDelete);
while(i.hasNext()){
FoldersList.removeAll(i.next());
}
return FoldersList; //return list without subfolders
}
/home/aar/las
/home/aar/.thumbnails
/home/aar/yfolder
/home/aar/.kde
=============================================== =========
尽管如此,我认为这不是大型列表的最佳和最快的方式。
有没有最好的方法来完成这项工作?
谢谢。
答案 0 :(得分:0)
沿着这些方向行事(使用std::vector
和std::string
代替QStringList
和QString
;适应Qt课程留给读者练习:< / p>
std::vector<std::string> v; // populated with directory paths
std::sort(v.begin(), v.end());
std::string root;
auto erase_from = std::unique(v.begin(), v.end(),
[&root](const std::string& a, const std::string& b) {
if (root.empty() || a.size() < root.size() || a.compare(0, root.size(), root) != 0) {
root = a;
}
return (b.size() >= root.size() && b.compare(0, root.size(), root) == 0);
}
);
v.erase(erase_from, v.end());
第二个想法,使用std::remove_if
会更简单,更有效:
std::vector<std::string> v; // populated with directory paths
std::sort(v.begin(), v.end());
std::string root;
auto erase_from = std::remove_if(v.begin(), v.end(),
[&root](const std::string& dir) {
if (root.empty() || dir.size() < root.size() ||
dir.compare(0, root.size(), root) != 0) {
root = dir;
return false;
}
return true;
}
);
v.erase(erase_from, v.end())
答案 1 :(得分:0)
这是一个黑客攻击:保留其中/
最少的路径
int pathDepth(const QString& path)
{
return std::count_if(path.begin(), path.end(), [](QChar c) { return c == '/'; });
}
QStringList getParentFolders(const QStringList& folderList)
{
QStringList ret;
int minDepth = pathDepth(*std::min_element(folderList.begin(), folderList.end(),
[](const QString& a, const QString& b){ return pathDepth(a) < pathDepth(b); }));
foreach (QString path, folderList)
if (pathDepth(path) == minDepth)
ret << path;
return ret;
}