Вы можете реализовать вспомогательную функцию для преобразования.
function convertRoundsToLeaderBoard(rounds) {
var indexes = {};
var leaderBoard = [];
for (var round of rounds) {
if (indexes[round.team] === undefined) {
indexes[round.team] = leaderBoard.length;
leaderBoard.push({
team: round.team,
rounds: [{score: round.score, course: round.course}]
});
} else {
leaderBoard[indexes[round.team]].rounds.push({score: round.score, course: round.course});
}
}
return leaderBoard;
}
Давайте проверим это:
convertRoundsToLeaderBoard(
[
{
team: "Dropkick Murphies",
score: 75,
course: 17
},
{
team: "Dropkick Murphies",
score: 62,
course: 24
},
{
team: "Dropkick Murphies",
score: 69,
course: 26
},
{
team: "Gigantic",
score: 67,
course: 26
},
{
team: "Gigantic",
score: 65,
course: 17
},
{
team: "Gigantic",
score: 63,
course: 24
}
]);
std::sort
берет другое, сравнивают функцию от используемого в qsort
. Вместо того, чтобы возвратиться –1, 0 или 1, эта функция, как ожидают, возвратит a bool
значение, указывающее, является ли первый элемент меньше, чем второе.
У Вас есть две возможности: реализация operator <
для Ваших объектов; в этом случае, значение по умолчанию sort
вызов без третьего аргумента будет работать; или можно переписать Ваш выше функции для выполнения того же самого.
Заметьте, что необходимо использовать строгий контроль типов в аргументах.
Кроме того, хорошо не использовать функцию здесь вообще. Вместо этого используйте функциональный объект. Они извлекают выгоду из встраивания.
struct pkt_less {
bool operator ()(pkt const& a, pkt const& b) const {
if (a.alfa < b.alfa) return true;
if (a.alfa > b.alfa) return false;
if (a.x < b.x) return true;
if (a.x > b.x) return false;
return false;
}
};
// Usage:
sort(wektor.begin(), wektor.end(), pkt_less());
В C++ можно использовать функторы как boost::bind
которые делают это задание приятно:
#include <vector>
#include <algorithm>
struct pkt {
double x;
double y;
double alfa;
pkt(double x, double y, double alfa)
:x(x), y(y), alfa(alfa) { }
};
int main() {
std::vector<pkt> p;
p.push_back(pkt(10., 0., 20.));
p.push_back(pkt(10, 0., 30.));
p.push_back(pkt(5., 0., 40.));
std::sort(p.begin(), p.end(),
boost::bind(&pkt::alfa, _1) < boost::bind(&pkt::alfa, _2) ||
boost::bind(&pkt::alfa, _1) == boost::bind(&pkt::alfa, _2) &&
boost::bind(&pkt::x, _1) < boost::bind(&pkt::x, _2));
}
Если необходимо много раз делать это, можно также решить проблему путем создания функционального объекта, который принимает членские указатели и делает вид. Можно снова использовать его для любого вида объекта и участников. Сначала, как Вы используете его:
int main() {
/* sorting a vector of pkt */
std::vector<pkt> p;
p.push_back(pkt(10., 0., 20.));
p.push_back(pkt(5., 0., 40.));
std::sort(p.begin(), p.end(), make_cmp(&pkt::x, &pkt::y));
}
Вот код для make_cmp. Не стесняйтесь разрывать его (использование boost::preprocessor
):
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
// tweak this to increase the maximal field count
#define CMP_MAX 10
#define TYPEDEF_print(z, n, unused) typedef M##n T::* m##n##_type;
#define MEMBER_print(z, n, unused) m##n##_type m##n;
#define CTORPARAMS_print(z, n, unused) m##n##_type m##n
#define CTORINIT_print(z, n, unused) m##n(m##n)
#define CMPIF_print(z, n, unused) \
if ((t0.*m##n) < (t1.*m##n)) return true; \
if ((t0.*m##n) > (t1.*m##n)) return false; \
#define PARAM_print(z, n, unused) M##n T::* m##n
#define CMP_functor(z, n, unused) \
template <typename T \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)> \
struct cmp##n { \
BOOST_PP_REPEAT(n, TYPEDEF_print, ~) \
BOOST_PP_REPEAT(n, MEMBER_print, ~) \
cmp##n(BOOST_PP_ENUM(n, CTORPARAMS_print, ~)) \
BOOST_PP_IF(n, :, BOOST_PP_EMPTY()) \
BOOST_PP_ENUM(n, CTORINIT_print, ~) { } \
\
bool operator()(T const& t0, T const& t1) const { \
BOOST_PP_REPEAT(n, CMPIF_print, ~) \
return false; \
} \
}; \
\
template<typename T \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)> \
cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)> \
make_cmp(BOOST_PP_ENUM(n, PARAM_print, ~)) \
{ \
return cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)>( \
BOOST_PP_ENUM_PARAMS(n, m)); \
}
BOOST_PP_REPEAT(CMP_MAX, CMP_functor, ~)
#undef TYPEDEF_print
#undef MEMBER_print
#undef CTORPARAMS_print
#undef CTORINIT_print
#undef CMPIF_print
#undef PARAM_print
#undef CMP_functor