summaryrefslogtreecommitdiff
path: root/src/discipline/Sport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/discipline/Sport.cpp')
-rw-r--r--src/discipline/Sport.cpp144
1 files changed, 132 insertions, 12 deletions
diff --git a/src/discipline/Sport.cpp b/src/discipline/Sport.cpp
index 42e82aa..1ea8019 100644
--- a/src/discipline/Sport.cpp
+++ b/src/discipline/Sport.cpp
@@ -1,6 +1,7 @@
#include "Sport.h"
#include <set>
+#include <map>
#include <algorithm>
#include <regex>
@@ -8,6 +9,21 @@
#include <QJsonArray>
#include <QJsonValueRef>
#include <QString>
+#include <QTime>
+
+// QJsonArray filter function, provide with input array and evaluation function
+QJsonArray filter(QJsonArray input, function<bool (QJsonObject)> eval) {
+ QJsonArray output;
+
+ for (const QJsonValueRef &elemRef :input) {
+ QJsonObject elem = elemRef.toObject();
+ if(eval(elem)) {
+ output.append(elem);
+ }
+ }
+
+ return output;
+}
// static compare function for specific attribute in competitors
function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QString attribute) {
@@ -20,21 +36,44 @@ function<bool (const QJsonValue &left, const QJsonValue &right)> genCompare(QStr
// static compare function for the results of a competitor in a specific competition (also called mark)
bool compareMark(const QJsonValue &left, const QJsonValue &right) {
+ // check if one competitor has no mark
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;
+ QString lMark = l["results"].toObject()["mark"].toString();
+ QString rMark = r["results"].toObject()["mark"].toString();
+
+ // check if the marks are numerical values
+ if (!lMark.contains(":") && !rMark.contains(":")) return lMark.toFloat() < rMark.toFloat();
+
+ // compare time values if not numerical
+ QString lTime(""), rTime("");
+
+ for (QChar c : lMark) if (c.isDigit()) lTime.append(c);
+ for (QChar c : rMark) if (c.isDigit()) rTime.append(c);
+
+ return lTime.compare(rTime) < 0;
+}
+
+// static compare function for the amount of medals a competitor has gotten
+bool compareMedals(const QJsonValue &left, const QJsonValue &right) {
+ QJsonObject lMedals = left.toObject()["medals"].toObject();
+ QJsonObject rMedals = right.toObject()["medals"].toObject();
+
+ int gold = lMedals["ME_GOLD"].toInt() - rMedals["ME_GOLD"].toInt();
+ int silver = lMedals["ME_SILVER"].toInt() - rMedals["ME_SILVER"].toInt();
+ int bronze = lMedals["ME_BRONZE"].toInt() - rMedals["ME_BRONZE"].toInt();
+
+ return gold < 0 || (gold == 0 && (silver < 0 || (silver == 0 && bronze < 0)));
}
/**
* @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) {
+void Sport::lastName(QJsonArray &competitors) {
for (int i = 0; i < competitors.size(); ++i) {
string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData();
@@ -64,7 +103,7 @@ void Sport::lastName(QJsonArray& competitors) {
set<QString> Sport::getCategories() {
set<QString> categoryNames;
- for (const QJsonValueRef& unit : this->discipline["units"].toArray()) {
+ for (const QJsonValueRef &unit : this->discipline["units"].toArray()) {
categoryNames.insert(unit.toObject()["eventUnitName"].toString());
}
@@ -79,21 +118,97 @@ set<QString> Sport::getCategories() {
QJsonArray Sport::getCompetitorsByCategory(QString category) {
QJsonArray competitors;
- for (const QJsonValueRef& unitRef : this->discipline["units"].toArray()) {
+ 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) {
+ if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue;
+
+ // add all competitors from one unit
+ for (const QJsonValueRef &comp : unit["competitors"].toArray()) {
+ competitors.push_back(comp.toObject());
+ }
+ }
+
+ return QJsonArray(competitors);
+}
+
+/**
+ * @brief Sport::getCompetitorsWithMedal Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!!
+ * @return All competitors, who won at least one medal. Structure of one competitor: {code, name, noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}}
+ */
+
+QJsonArray Sport::getCompetitorsWithMedal() {
+ map<QString, QJsonObject> competitors;
+
+ // filter all units, which have medal events
+ 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
+ QString unitName = unit["eventUnitName"].toString();
+ return unitName.contains("Bronze", Qt::CaseSensitive)
+ || unitName.contains("Gold", Qt::CaseSensitive)
+ || unitName.contains("Final", Qt::CaseSensitive);
+ });
+
+ for (const QJsonValueRef &unitRef : units) {
+ QJsonObject unit = unitRef.toObject();
+
+ // filter all competitors, who won medals
+ QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {
+ if (!comp.contains("results")) return false;
- // add all competitors from one unit
- for (const QJsonValueRef& comp : unit["competitors"].toArray()) {
- competitors.push_back(comp.toObject());
+ QString medalType = comp["results"].toObject()["medalType"].toString();
+ return !medalType.isEmpty();
+ });
+
+ for (const QJsonValueRef &medalCompRef : medalComps) {
+ QJsonObject medalComp = medalCompRef.toObject();
+
+ QString name = medalComp["name"].toString();
+ QString medalType = medalComp["results"].toObject()["medalType"].toString();
+
+ // check if competitor has other medal(s)
+ if (competitors.find(name) == competitors.end()) {
+ competitors.insert({name, createCompetitorWithMedals(medalComp)});
}
+ // update the medal count
+ QJsonObject updatedMedalCount = QJsonObject(competitors.find(name)->second["medals"].toObject());
+
+ int amount = updatedMedalCount[medalType].toInt() + 1;
+ updatedMedalCount.remove(medalType);
+ updatedMedalCount.insert(medalType, amount);
+
+ // create new medals QJsonObject and set it in the map
+ competitors.find(name)->second["medals"] = updatedMedalCount;
}
}
- return QJsonArray(competitors);
+ // convert map to QJsonArray
+ QJsonArray output;
+ for (const pair<QString, QJsonObject> &competitor : competitors) {
+ output.append(competitor.second);
+ }
+
+ return output;
+}
+
+QJsonObject Sport::createCompetitorWithMedals(QJsonObject comp) {
+ // create new competitor QJsonObject and add it to the competitor map
+ QJsonObject medals {
+ {"ME_GOLD", 0},
+ {"ME_SILVER", 0},
+ {"ME_BRONZE", 0}
+ };
+
+ QJsonObject medalComp {
+ {"code", comp["code"].toString()},
+ {"name", comp["name"].toString()},
+ {"noc", comp["noc"].toString()},
+ {"medals", medals}
+ };
+
+ return medalComp;
}
/**
@@ -147,7 +262,12 @@ void Sport::sortByCountry(QJsonArray &competitors) {
* @param competitors The competitors of one category.
*/
void Sport::sortByResult(QJsonArray &competitors) {
- sortCompetitors(competitors, compareMark);
+ if (competitors.isEmpty()) return;
+
+ QJsonObject comp = competitors[0].toObject();
+
+ if (comp.contains("results")) sortCompetitors(competitors, compareMark);
+ else if (comp.contains("medals")) sortCompetitors(competitors, compareMedals);
}
void Sport::sortCompetitors(QJsonArray &competitors, function<bool (const QJsonValue &left, const QJsonValue &right)> compare) {