Added guards for a little more stability.
This commit is contained in:
parent
77f8836508
commit
2476684e3c
|
@ -9,7 +9,6 @@
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonValueRef>
|
#include <QJsonValueRef>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTime>
|
|
||||||
|
|
||||||
// QJsonArray filter function, provide with input array and evaluation function
|
// QJsonArray filter function, provide with input array and evaluation function
|
||||||
QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {
|
QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {
|
||||||
|
@ -74,28 +73,43 @@ bool compareMedals(const QJsonValue &left, const QJsonValue &right) {
|
||||||
* @param competitors The competitors of one category.
|
* @param competitors The competitors of one category.
|
||||||
*/
|
*/
|
||||||
void Sport::lastName(QJsonArray &competitors) {
|
void Sport::lastName(QJsonArray &competitors) {
|
||||||
|
// validate competitors
|
||||||
|
if (competitors.isEmpty() || !competitors[0].toObject().contains("name")) return;
|
||||||
|
|
||||||
for (int i = 0; i < competitors.size(); ++i) {
|
for (int i = 0; i < competitors.size(); ++i) {
|
||||||
string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData();
|
string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData();
|
||||||
|
|
||||||
|
// regex to identify names, written in CAPS
|
||||||
regex r("[A-Z']{2,}");
|
regex r("[A-Z']{2,}");
|
||||||
smatch m;
|
smatch m;
|
||||||
|
|
||||||
regex_search(fullName, m, r);
|
regex_search(fullName, m, r);
|
||||||
|
|
||||||
|
// combine found names again
|
||||||
string lastName = "";
|
string lastName = "";
|
||||||
for (string s : m) {
|
for (string s : m) lastName = lastName + s + " ";
|
||||||
lastName = lastName + s + " ";
|
|
||||||
}
|
// remove last space
|
||||||
QJsonValue nameValue = QJsonValue(QString(lastName.substr(0, lastName.size() - 1).c_str()));
|
QJsonValue nameValue = QJsonValue(QString(lastName.substr(0, lastName.size() - 1).c_str()));
|
||||||
|
|
||||||
|
// create new object with replaced name
|
||||||
QJsonObject comp(competitors[i].toObject());
|
QJsonObject comp(competitors[i].toObject());
|
||||||
comp.remove("name");
|
comp.remove("name");
|
||||||
comp.insert("name", nameValue);
|
comp.insert("name", nameValue);
|
||||||
|
|
||||||
competitors[i] = comp;
|
// replace competitor in array
|
||||||
|
competitors.replace(i, comp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sport::validateDiscipline Validates the discipline object. Checks for the units attribute.
|
||||||
|
* @return True, if discipline contains units.
|
||||||
|
*/
|
||||||
|
bool Sport::validateDiscipline() {
|
||||||
|
return this->discipline.contains("units");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sport::getCategories Reads all possible categories (also called units).
|
* @brief Sport::getCategories Reads all possible categories (also called units).
|
||||||
* @return A set of all category names.
|
* @return A set of all category names.
|
||||||
|
@ -103,8 +117,16 @@ void Sport::lastName(QJsonArray &competitors) {
|
||||||
set<QString> Sport::getCategories() {
|
set<QString> Sport::getCategories() {
|
||||||
set<QString> categoryNames;
|
set<QString> categoryNames;
|
||||||
|
|
||||||
for (const QJsonValueRef &unit : this->discipline["units"].toArray()) {
|
if (!validateDiscipline()) return categoryNames;
|
||||||
categoryNames.insert(unit.toObject()["eventUnitName"].toString());
|
|
||||||
|
// search in each unit for the category (named "eventUnitName")
|
||||||
|
for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {
|
||||||
|
QJsonObject unit = unitRef.toObject();
|
||||||
|
|
||||||
|
// validate unit
|
||||||
|
if (!unit.contains("eventUnitName")) continue;
|
||||||
|
|
||||||
|
categoryNames.insert(unit["eventUnitName"].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return categoryNames;
|
return categoryNames;
|
||||||
|
@ -118,15 +140,20 @@ set<QString> Sport::getCategories() {
|
||||||
QJsonArray Sport::getCompetitorsByCategory(QString category) {
|
QJsonArray Sport::getCompetitorsByCategory(QString category) {
|
||||||
QJsonArray competitors;
|
QJsonArray competitors;
|
||||||
|
|
||||||
|
if (!validateDiscipline()) return competitors;
|
||||||
|
|
||||||
for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {
|
for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {
|
||||||
QJsonObject unit = unitRef.toObject();
|
QJsonObject unit = unitRef.toObject();
|
||||||
|
|
||||||
|
// validate unit
|
||||||
|
if (!unit.contains("eventUnitName") || !unit.contains("competitors")) continue;
|
||||||
|
|
||||||
// search all units with the same category
|
// search all units with the same category
|
||||||
if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue;
|
if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue;
|
||||||
|
|
||||||
// add all competitors from one unit
|
// add all competitors from one unit
|
||||||
for (const QJsonValueRef &comp : unit["competitors"].toArray()) {
|
for (const QJsonValueRef &compRef : unit["competitors"].toArray()) {
|
||||||
competitors.push_back(comp.toObject());
|
competitors.push_back(compRef.toObject());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +168,8 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {
|
||||||
QJsonArray Sport::getCompetitorsWithMedal() {
|
QJsonArray Sport::getCompetitorsWithMedal() {
|
||||||
map<QString, QJsonObject> competitors;
|
map<QString, QJsonObject> competitors;
|
||||||
|
|
||||||
|
if (!validateDiscipline()) return QJsonArray();
|
||||||
|
|
||||||
// filter all units, which have medal events
|
// filter all units, which have medal events
|
||||||
QJsonArray units = filter(this->discipline["units"].toArray(), [](QJsonObject unit){
|
QJsonArray units = filter(this->discipline["units"].toArray(), [](QJsonObject unit){
|
||||||
// search all units with Final, Gold or Bronze in their name, because these are the categories with the medal winners
|
// search all units with Final, Gold or Bronze in their name, because these are the categories with the medal winners
|
||||||
|
@ -153,6 +182,9 @@ QJsonArray Sport::getCompetitorsWithMedal() {
|
||||||
for (const QJsonValueRef &unitRef : units) {
|
for (const QJsonValueRef &unitRef : units) {
|
||||||
QJsonObject unit = unitRef.toObject();
|
QJsonObject unit = unitRef.toObject();
|
||||||
|
|
||||||
|
// validate unit
|
||||||
|
if (!unit.contains("competitors")) continue;
|
||||||
|
|
||||||
// filter all competitors, who won medals
|
// filter all competitors, who won medals
|
||||||
QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {
|
QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {
|
||||||
if (!comp.contains("results")) return false;
|
if (!comp.contains("results")) return false;
|
||||||
|
@ -164,6 +196,11 @@ QJsonArray Sport::getCompetitorsWithMedal() {
|
||||||
for (const QJsonValueRef &medalCompRef : medalComps) {
|
for (const QJsonValueRef &medalCompRef : medalComps) {
|
||||||
QJsonObject medalComp = medalCompRef.toObject();
|
QJsonObject medalComp = medalCompRef.toObject();
|
||||||
|
|
||||||
|
// validate competitor (with medal)
|
||||||
|
if (!medalComp.contains("name")
|
||||||
|
|| !medalComp.contains("results")
|
||||||
|
|| !medalComp["results"].toObject().contains("medalType")) continue;
|
||||||
|
|
||||||
QString name = medalComp["name"].toString();
|
QString name = medalComp["name"].toString();
|
||||||
QString medalType = medalComp["results"].toObject()["medalType"].toString();
|
QString medalType = medalComp["results"].toObject()["medalType"].toString();
|
||||||
|
|
||||||
|
@ -193,7 +230,17 @@ QJsonArray Sport::getCompetitorsWithMedal() {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sport::createCompetitorWithMedals Creates a competitor QJsonObject with the following attributes: code, name, noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}
|
||||||
|
* @param comp The original competitor object.
|
||||||
|
* @return A competitor object with medal counts.
|
||||||
|
*/
|
||||||
QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {
|
QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {
|
||||||
|
// repair competitor if something is missing
|
||||||
|
if (!comp.contains("code")) comp.insert("code", "0");
|
||||||
|
if (!comp.contains("name")) comp.insert("code", "");
|
||||||
|
if (!comp.contains("noc")) comp.insert("code", "");
|
||||||
|
|
||||||
// create new competitor QJsonObject and add it to the competitor map
|
// create new competitor QJsonObject and add it to the competitor map
|
||||||
QJsonObject medals {
|
QJsonObject medals {
|
||||||
{"ME_GOLD", 0},
|
{"ME_GOLD", 0},
|
||||||
|
@ -229,10 +276,17 @@ void Sport::filterByCountry(QJsonArray &competitors, QString nocShort) {
|
||||||
filterCompetitors(competitors, QString("noc"), nocShort);
|
filterCompetitors(competitors, QString("noc"), nocShort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sport::filterCompetitors Filters the given QJsonArray by comparing the value of a certain attribute with the given filter string.
|
||||||
|
* @param competitors The competitors of one category.
|
||||||
|
* @param attribute The attribute to filter by.
|
||||||
|
* @param filter The string, which should be contained.
|
||||||
|
*/
|
||||||
void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) {
|
void Sport::filterCompetitors(QJsonArray &competitors, QString attribute, QString filter) {
|
||||||
for (int i = 0; i < competitors.size(); i++) {
|
for (int i = 0; i < competitors.size(); i++) {
|
||||||
|
QJsonObject comp = competitors[i].toObject();
|
||||||
|
|
||||||
if (!competitors[i].toObject()[attribute].toString().contains(filter, Qt::CaseInsensitive)) {
|
if (!comp.contains(attribute) || !comp[attribute].toString().contains(filter, Qt::CaseInsensitive)) {
|
||||||
// remove the competitor, if the attribute does not fit the filter string
|
// remove the competitor, if the attribute does not fit the filter string
|
||||||
competitors.removeAt(i);
|
competitors.removeAt(i);
|
||||||
i--;
|
i--;
|
||||||
|
@ -270,6 +324,11 @@ void Sport::sortByResult(QJsonArray &competitors) {
|
||||||
else if (comp.contains("medals")) sortCompetitors(competitors, compareMedals);
|
else if (comp.contains("medals")) sortCompetitors(competitors, compareMedals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sport::sortCompetitors Sorts the given QJsonArray according to the compare function.
|
||||||
|
* @param competitors The competitors of one category.
|
||||||
|
* @param compare A function to compare two competitors with each other. This defines the order.
|
||||||
|
*/
|
||||||
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {
|
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {
|
||||||
make_heap(competitors.begin(), competitors.end(), compare);
|
make_heap(competitors.begin(), competitors.end(), compare);
|
||||||
sort_heap(competitors.begin(), competitors.end(), compare);
|
sort_heap(competitors.begin(), competitors.end(), compare);
|
||||||
|
|
|
@ -76,6 +76,8 @@ private:
|
||||||
|
|
||||||
void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);
|
void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);
|
||||||
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
|
void sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare);
|
||||||
|
|
||||||
|
bool validateDiscipline();
|
||||||
QJsonObject createCompetitorWithMedals(QJsonObject medalComp);
|
QJsonObject createCompetitorWithMedals(QJsonObject medalComp);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue