想象一下:我有一个JSON文件,其中包含Node
个对象列表,其中包含Link
类型的列表。类似的东西:
node1:
links: node1,node2
node3,node1
node1,node6
node2:
links: node2,node1
node2,node9
node7,node2
我需要识别唯一的链接对 - 即(node_a,node_b)
对。请注意,(node_b,node_a)
代表相同的内容。
Link
类具有getter方法,返回指向源/目标Node
的指针。在该文件中,有关链接的信息存储为具有source
节点名称和destination
节点名称的字符串,如:(source,destination)
。
当我从文件构建我的结构时,我首先创建Nodes
然后才创建Links
。 Link
构造函数如下:
Link::Link(Node *fromNode, Node *toNode)
我的代码创建链接:
QList<Link*> consumedLinks; // list where I was trying to place all the non-duplicate links
// for each node in the file
foreach(QVariant nodesMap, allNodesList){
QVariantMap node1 = nodesMap.toMap();
QList<QVariant> nodeDetails = node1["node"].toList();
QVariantMap allLinksMap = nodeDetails.at(9).toMap();
// extract all the links of the node to a list of QVariant
QList<QVariant> linksList = allLinksMap["links"].toList();
// for each Link in that list
foreach(QVariant linkMap, linksList){
QVariantMap details = linkMap.toMap();
Node *savedFromNode;
Node *savedToNode;
// get all the Items in the scene
QList<QGraphicsItem*> itemList = scene->items();
// cast each item to a Node
foreach(QGraphicsItem *item, itemList){
Node* tempNode = qgraphicsitem_cast<Node*>(item);
if(tempNode){
// check what the node name matches in the link list
if(tempNode->text()==details["fromNode"]){
savedFromNode = tempNode;
}
if(tempNode->text()==details["toNode"]){
savedToNode = tempNode;
}
}
}
// create the link
Link *linkToCheck = new Link(savedFromNode,savedToNode);
// add it to the links list (even if duplicate)
consumedLinks.append(linkToCheck);
}
}
// add all the links as graphics items in the scene
foreach(Link *linkToCheck, consumedLinks){
scene->addItem(linkToCheck);
}
所以现在这不会检查consumedLinks
列表中的重复项(显然)。关于如何实现这一点的任何想法?
注意:我知道上面的伪JSON无效,只是为了让您了解结构。
注意2:我重新说明并在问题中添加了详细信息和代码,以便更清楚地了解我需要的内容。
答案 0 :(得分:1)
1.
规范化链接,即(a, b)
时将(b, a)
替换为b < a
。每个链接都应表示为(a, b)
,a < b
。
2.
创建一个QSet< QPair<Node*, Node *> >
变量并将所有链接放入其中。可以使用qMakePair(node1, node2)
制作每个链接对象。由于QSet
是一个qnique容器,因此将自动删除所有重复项。
答案 1 :(得分:0)
好吧,我并没有像@Riateche所建议的那样做,但类似的东西。
我基本上创建了一个QList<QPair<QString,QString> >
,因此我可以轻松检查重复项,然后根据Link
列表中的项目创建了QPair
列表。类似的东西:
QList<Node*> existingNodes;
QList<QPair<QString,QString> > linkPairList;
QList<QGraphicsItem*> itemList = scene->items();
foreach(QGraphicsItem *item, itemList){
Node* tempNode = qgraphicsitem_cast<Node*>(item);
if(tempNode){
existingNodes.append(tempNode);
}
}
foreach(QVariant nodesMap, allNodesList){
QVariantMap node1 = nodesMap.toMap();
QList<QVariant> nodeDetails = node1["node"].toList();
QVariantMap allLinksMap = nodeDetails.at(9).toMap();
QList<QVariant> linksList = allLinksMap["links"].toList();
foreach(QVariant linkMap, linksList){
QVariantMap details = linkMap.toMap();
QPair<QString,QString>linkPair(details["fromNode"].toString(),details["toNode"].toString());
QPair<QString,QString>reversedLinkPair(details["toNode"].toString(),details["fromNode"].toString());
if(!linkPairList.contains(linkPair)){
// !dupe
if(!linkPairList.contains(reversedLinkPair)){
// !reversed dupe
linkPairList.append(linkPair);
}
}
qDebug()<<"number of pairs: "<<linkPairList.size();
}
}
QPair<QString,QString> linkPairInList;
foreach(linkPairInList, linkPairList){
Node *savedFromNode;
Node *savedToNode;
foreach(Node* node, existingNodes){
if(node->text()==linkPairInList.first){
savedFromNode=node;
}
if(node->text()==linkPairInList.second){
savedToNode=node;
}
}
Link *newLink = new Link(savedFromNode,savedToNode, "input");
scene->addItem(newLink);
}
这是正确的答案,因为它解决了我需要解决的问题。因为我只是因为@ Riateche的评论而到达那里,所以我给他的答案+1了。