【问题标题】:How to convert QList to QSet in Qt 6如何在 Qt 6 中将 QList 转换为 QSet
【发布时间】:2021-05-13 08:02:22
【问题描述】:

我正在将我的应用程序移植到 Qt 6,当我阅读文档时,我看到类被清理了很多,QListQVector 是统一的,QStringList 现在是 QList<QString> 的别名等等.

但是现在这给了我一个问题。

在我的代码(即 Qt 5)中,我将 QStringList 转换为 QSet 以消除列表中的重复项。我浏览了新文档,但我还没有看到在 Qt 6 中将 QList 转换为 QSet 的方法。

那么如何将QList 转换为QSet?或者这是不可能的,我需要编写一个辅助函数来删除重复项?

编辑:我使用的是 Qt 6.0.1。

【问题讨论】:

  • 消除是为了完全避免您的次优用例。如果您想删除所有欺骗,请使用 std::unique。如果你真的想要一个 QSet 使用 QSet(InputIterator first, InputIterator last)
  • QStringList::removeDuplicates() 有什么问题? :-)

标签: c++ list qt set qt6


【解决方案1】:

我必须承认我还在使用 Qt5。

但是,QListQSet 强烈提醒我注意 std::liststd::set。 对于后者,已经有另一种(更灵活)的方式来实现这些目标: 使用带有迭代器的构造。 Qt6 文档中的简短检查。说服我,这也应该适用于 Qt 类:

QSet::QSet(InputIterator first, InputIterator last)

用迭代器范围 [first, last) 中的内容构造一个集合。

InputIterator 的值类型必须可转换为 T。

注意:如果范围 [first, last) 包含重复元素,则保留第一个。

这个函数是在 Qt 5.14 中引入的。

first 的设置位置

QList::iterator QList::begin()

返回一个指向列表中第一项的 STL 风格的迭代器。

last 一起

QList::iterator QList::end()

返回一个 STL 风格的迭代器,指向列表中最后一项之后的虚构项。

放在一起应该是什么样子:

QList<QString> aList;
// populate list
QSet<QString> aSet(aList.begin(), aList.end());

OP 注意到 Qt-5 文档。已经包含有关此的提示:

QSet QList::toSet() const

注意:从 Qt 5.14 开始,范围构造函数可用于 Qt 的通用容器类,并且应该用来代替此方法。

OP 还提到了一个方便的包装器:

template <typename T>
QSet<T> QListToQSet(const QList<T>& qlist)
{
  return QSet<T> (qlist.constBegin(), qlist.constEnd());
}

应用于上述示例:

QList<QString> aList;
// populate list
QSet<QString> aSet = QListToQSet(aList);

更通用的转换工具可能是这样的:

template <typename T, template<typename> typename C>
QSet<T> toQSet(const C<T> &container)
{
  return QSet<T>(container.begin(), container.end());
}

即使与匹配的 std 容器也可以使用:

std::vector<QString> aVec = { "Hello", "World", "Hello" };
QSet<QString> aSet = toSet(aVec);

【讨论】:

  • 是的!这正是我几分钟前所做的事情,我正打算回答我自己的问题,但你在我之前做到了。 :) 我正在挖掘 Qt 5.15 并看到他们有弃用警告'toSet' is deprecated: Use QSet&lt;T&gt; (list.begin(), list.end()) 所以我做了:template &lt;typename T&gt; QSet&lt;T&gt; QListToQSet(const QList&lt;T&gt;&amp; qlist) { return QSet&lt;T&gt; (qlist.constBegin(), qlist.constEnd()); }。如果您可以将此模板添加到您的答案中,那就太好了,我已经接受了它作为答案。 :)
  • 尽管如此,它为你带来了回报:我提供了一个“复仇投票”。 ;-) 我将在信息中编辑弃用。
【解决方案2】:

你是对的,在codedoc 中看到 QStringList 是 QList 的子项

class QStringList : public QList<QString>
{

所以你可以调用 QSet toSet() const;直接因为方法是公开的。

有了这个,你可以直接将QStringlist的内容解压到一个qset

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QString str = "one,two,three,four,one";
    QStringList strlt = str.split(QChar(','));

    const QSet<QString> strVe = strlt.toSet();
    qDebug() << strVe;

    return a.exec();
}

【讨论】:

  • 当然,但 OP 正在询问 doc.qt.io/Qt-6/qstringlist.html#details 但感谢兄弟的评论!
  • 我很困惑原来的问题是什么,因为我希望使用.toSet();,但我还没有使用 Qt6。
  • 这正是我问这个问题的问题和原因。 QList 中没有方法 toSet()。 ( b) 与 cmets 一起记录并没有找到任何东西。之后我在这里写了这个问题。现在我尝试了你的示例,但仍然有关于 no member 的错误。PS 我使用的是 Qt 6.0.1(我会把它放入编辑)。
猜你喜欢
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多