Консолидировать массив на основе значения общего свойства

Я пишу небольшое маленькое приложение от VueJS и ExpressionEngine, которое отображает таблицу лидеров турниров по гольфу. Турнир может потребовать, чтобы вы играли более чем на один курс. Данные, поступающие из базы данных, показаны ниже (раунды).

Проблема в том, что мне нужно реструктурировать массив раундов, чтобы он выглядел как массив таблицы лидеров. У меня есть блок писателей о том, как это сделать. Любое руководство будет чрезвычайно цениться!

rounds: [
   {
      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
   }
]
leaderboard: [
   {
      team: 'Dropkick Murphys',
      rounds: [
         {
            score: 75,
            course: 17
         },
         {
            score: 62,
            course: 24
         },
         {
            score: 69,
            course: 26
         },
   },
   {
      team: 'Wooden Jellyfishes',
      rounds: [
         {
            score: 68,
            course: 24
         },
         {
            score: 65,
            course: 17
         },
         {
            score: 70,
            course: 26
         }
   },
]

-5
задан Luke 17 January 2019 в 15:44
поделиться

5 ответов

Вероятно, не самое элегантное решение, но вот другое:

var data = {
    rounds: [{
            team: "Dropkick Murphies",
            score: 75,
            course: 17
        },
        ...
    ]
};

var groups = {};
for (var o of data.rounds) {
    if (!groups[o.team])
        groups[o.team] = [];
    groups[o.team].push({
        score: o.score,
        course: o.course
    });
}
var result = [];
for (var g in groups) {
    result.push({
        team: g,
        rounds: groups[g]
    });
}
0
ответ дан areyesram 17 January 2019 в 15:44
поделиться

Одним из подходов для этого является использование Reduce () . На каждой итерации вы можете проверить, существует ли текущий анализируемый объект в накопленном массиве (т. Е. Объект с тем же team name уже существует). Затем вы можете использовать это условие для добавления нового целого объекта в накопленный массив или просто добавить новый набор данных в массив rounds:

const rounds = [
   {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}
];

let res = rounds.reduce((r, {team, score, course}) =>
{
   let found = r.findIndex(x => x.team === team);
   
   if (found >= 0)
       r[found].rounds.push({score: score, course: course});
   else
       r.push({team: team, rounds: [{score: score, course: course}]});

   return r;

}, []);

console.log(res);
[ 114]

0
ответ дан Shidersz 17 January 2019 в 15:44
поделиться

Вы можете сделать это, используя Reduce.

здесь мы используем team name в качестве ключевого свойства и, проверяя, находится ли он уже в выходном объекте, нажимаем score и course в свойстве раундов этого конкретного командного ключа, если нет, то мы создаем новый ключ.

const rounds = [
   {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}
];

let op = rounds.reduce((output,current)=>{
  if(output[current.team]){
    output[current.team].rounds.push({
      score : current.score,
      course: current.score
    })} else {
      output[current.team] = {
        team: current.team,
        rounds: [{score:current.score, course:current.course}]
      }
    }
 return output 
},{})

console.log(Object.values(op))

0
ответ дан Code Maniac 17 January 2019 в 15:44
поделиться

Вы можете реализовать вспомогательную функцию для преобразования.

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
   }
]);
0
ответ дан Lajos Arpad 17 January 2019 в 15:44
поделиться

Я бы посоветовал вводить ваши данные командой, используя Map. Таким образом, вы можете построить свои данные с помощью цикла forEach с линейной сложностью времени:

const rounds = [{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}];

// Create Map with one entry per team
const map = new Map(rounds.map(({team}) => [team, []]));
// Populate each team with their scores
rounds.forEach(({team,score,course}) => map.get(team).push({score,course}));
// Convert the Map to the desired data structure
const result = Array.from(map, ([team, rounds]) => ({team, rounds}));

console.log(result);

0
ответ дан trincot 17 January 2019 в 15:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: