itat_challenge/src/discipline/Sport.cpp

158 lines
5.3 KiB
C++
Raw Normal View History

#include "Sport.h"
#include <set>
#include <algorithm>
#include <regex>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValueRef>
#include <QString>
// static compare function for specific attribute in competitors
function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) {
return [attribute](const QJsonValue &left, const QJsonValue &right) {
QString l = left.toObject()[attribute].toString();
QString r = right.toObject()[attribute].toString();
return l.compare(r) < 0;
};
}
// static compare function for the results of a competitor in a specific competition (also called mark)
bool compareMark(const QJsonValue &left, const QJsonValue &right) {
QJsonObject l = left.toObject();
if (!l.contains("results")) return true;
QJsonObject r = right.toObject();
if (!r.contains("results")) return false;
float lMark = l["results"].toObject()["mark"].toString().toFloat();
float rMark = r["results"].toObject()["mark"].toString().toFloat();
return lMark < rMark;
}
/**
* @brief Sport::lastName Reduce the full name to the part that is marked in capital letters (probably last name).
* @param competitors The competitors of one category.
*/
void Sport::lastName(QJsonArray& competitors) {
for (int i = 0; i < competitors.size(); ++i) {
string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData();
regex r("[A-Z']{2,}");
smatch m;
regex_search(fullName, m, r);
string lastName = "";
for (string s : m) {
lastName = lastName + s + " ";
}
QJsonValue nameValue = QJsonValue(QString(lastName.substr(0, lastName.size() - 1).c_str()));
QJsonObject comp(competitors[i].toObject());
comp.remove("name");
comp.insert("name", nameValue);
competitors[i] = comp;
}
}
/**
* @brief Sport::getCategories Reads all possible categories (also called units).
* @return A set of all category names.
*/
set<QString> Sport::getCategories() {
set<QString> categoryNames;
for (const QJsonValueRef& unit : this->discipline["units"].toArray()) {
categoryNames.insert(unit.toObject()["eventUnitName"].toString());
}
return categoryNames;
}
/**
* @brief Sport::getCompetitorsByCategory Searches for all competitors, who took part in the given category.
* @param category The category to search in.
* @return An QJsonArray with all competitors as QJsonValueRef, which can be casted to QJsonObject.
*/
QJsonArray Sport::getCompetitorsByCategory(QString category) {
QJsonArray competitors;
for (const QJsonValueRef& unitRef : this->discipline["units"].toArray()) {
QJsonObject unit = unitRef.toObject();
// search all units with the same category
if (QString::compare(unit["eventUnitName"].toString(), category, Qt::CaseSensitive) == 0) {
// add all competitors from one unit
for (const QJsonValueRef& comp : unit["competitors"].toArray()) {
competitors.push_back(comp.toObject());
}
}
}
return QJsonArray(competitors);
}
/**
* @brief Sport::filterByName Filter the competitors by name (case insensitive).
* @param competitors The competitors of one category.
* @param name The (part of the) name to search for.
*/
void Sport::filterByName(QJsonArray &competitors, QString name) {
filterCompetitors(competitors, QString("name"), name);
}
/**
* @brief Sport::filterByCountry Filter the competitors by their national olympics comittee (case insensitive, short form).
* @param competitors The competitors of one category.
* @param nocShort The (part of the) national olympics comittee short name to search for.
*/
void Sport::filterByCountry(QJsonArray &competitors, QString nocShort) {
filterCompetitors(competitors, QString("noc"), nocShort);
}
void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) {
for (int i = 0; i < competitors.size(); i++) {
if (!competitors[i].toObject()[attribute].toString().contains(filter, Qt::CaseInsensitive)) {
// remove the competitor, if the attribute does not fit the filter string
competitors.removeAt(i);
i--;
}
}
}
/**
* @brief Sport::sortByName Sort the competitors by their name (alphabetical, ascending).
* @param competitors The competitors of one category.
*/
void Sport::sortByName(QJsonArray &competitors) {
sortCompetitors(competitors, genCompare( QString("name") ));
}
/**
* @brief Sport::sortByCountry Sort the competitors by their national olympic comittee short name (alphabetical, ascending).
* @param competitors The competitors of one category.
*/
void Sport::sortByCountry(QJsonArray &competitors) {
sortCompetitors(competitors, genCompare( QString("noc") ));
}
/**
* @brief Sport::sortByResult Sort the competitors by their results in one specific category (numerical, ascending).
* @param competitors The competitors of one category.
*/
void Sport::sortByResult(QJsonArray &competitors) {
sortCompetitors(competitors, compareMark);
}
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {
make_heap(competitors.begin(), competitors.end(), compare);
sort_heap(competitors.begin(), competitors.end(), compare);
}