diff options
| -rw-r--r-- | src/discipline/Sport.cpp | 79 | ||||
| -rw-r--r-- | src/discipline/Sport.h | 2 | 
2 files changed, 71 insertions, 10 deletions
| diff --git a/src/discipline/Sport.cpp b/src/discipline/Sport.cpp index 1ea8019..8d9a5c2 100644 --- a/src/discipline/Sport.cpp +++ b/src/discipline/Sport.cpp @@ -9,7 +9,6 @@  #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) { @@ -74,37 +73,60 @@ bool compareMedals(const QJsonValue &left, const QJsonValue &right) {   * @param competitors The competitors of one category.   */  void Sport::lastName(QJsonArray &competitors) { +    // validate competitors +    if (competitors.isEmpty() || !competitors[0].toObject().contains("name")) return; +      for (int i = 0; i < competitors.size(); ++i) {          string fullName = competitors[i].toObject()["name"].toString().toUtf8().constData(); +        // regex to identify names, written in CAPS          regex r("[A-Z']{2,}");          smatch m;          regex_search(fullName, m, r); +        // combine found names again          string lastName = ""; -        for (string s : m) { -            lastName = lastName + s + " "; -        } +        for (string s : m) lastName = lastName + s + " "; + +        // remove last space          QJsonValue nameValue = QJsonValue(QString(lastName.substr(0, lastName.size() - 1).c_str())); +        // create new object with replaced name          QJsonObject comp(competitors[i].toObject());          comp.remove("name");          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).   * @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()); +    if (!validateDiscipline()) return categoryNames; + +    // 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; @@ -118,15 +140,20 @@ set<QString> Sport::getCategories() {  QJsonArray Sport::getCompetitorsByCategory(QString category) {      QJsonArray competitors; +    if (!validateDiscipline()) return competitors; +      for (const QJsonValueRef &unitRef : this->discipline["units"].toArray()) {          QJsonObject unit = unitRef.toObject(); +        // validate unit +        if (!unit.contains("eventUnitName") || !unit.contains("competitors")) continue; +          // search all units with the same category          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()); +        for (const QJsonValueRef &compRef : unit["competitors"].toArray()) { +            competitors.push_back(compRef.toObject());          }      } @@ -141,6 +168,8 @@ QJsonArray Sport::getCompetitorsByCategory(QString category) {  QJsonArray Sport::getCompetitorsWithMedal() {      map<QString, QJsonObject> competitors; +    if (!validateDiscipline()) return QJsonArray(); +      // 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 @@ -153,6 +182,9 @@ QJsonArray Sport::getCompetitorsWithMedal() {      for (const QJsonValueRef &unitRef : units) {          QJsonObject unit = unitRef.toObject(); +        // validate unit +        if (!unit.contains("competitors")) continue; +          // filter all competitors, who won medals          QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {              if (!comp.contains("results")) return false; @@ -164,6 +196,11 @@ QJsonArray Sport::getCompetitorsWithMedal() {          for (const QJsonValueRef &medalCompRef : medalComps) {              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 medalType = medalComp["results"].toObject()["medalType"].toString(); @@ -193,7 +230,17 @@ QJsonArray Sport::getCompetitorsWithMedal() {      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) { +    // 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      QJsonObject medals {          {"ME_GOLD", 0}, @@ -229,10 +276,17 @@ void Sport::filterByCountry(QJsonArray &competitors, QString 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) {      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              competitors.removeAt(i);              i--; @@ -270,6 +324,11 @@ void Sport::sortByResult(QJsonArray &competitors) {      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) {      make_heap(competitors.begin(), competitors.end(), compare);      sort_heap(competitors.begin(), competitors.end(), compare); diff --git a/src/discipline/Sport.h b/src/discipline/Sport.h index 9156b82..9175ad0 100644 --- a/src/discipline/Sport.h +++ b/src/discipline/Sport.h @@ -76,6 +76,8 @@ private:      void filterCompetitors(QJsonArray &competitors, QString attribute, QString filter);      void sortCompetitors(QJsonArray &competitors,  function<bool (const QJsonValue &left, const QJsonValue &right)> compare); + +    bool validateDiscipline();      QJsonObject createCompetitorWithMedals(QJsonObject medalComp);  }; | 
