Как преобразовать многомерный массив в данные диаграммы с помощью методов массива es6 - PullRequest
0 голосов
/ 25 июня 2018

Мне нужно преобразовать один массив в определенный формат данных для отображения диаграммы.

В библиотеке chrat.js требуются данные в этом формате

dataset = [ { label: 'one', data: []}, 
           {label: 'two', data: []}
        ];

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

вот мой код и пробная версия.

const dataset = [
    {
        detail: {
            team: [
                { name: 'alpha', game: 1 },
                { name: 'beta', game: 1 },
                { name: 'gamma', game: 1 },
                { name: 'delta', game: 1 },
                { name: 'echo', game: 1 }
            ]
        }
    },
    {
        detail: {
            team: [
                { name: 'alpha', game: 2 },
                { name: 'beta', game: 2 },
                { name: 'echo', game: 2 },
                { name: 'gamma', game: 2 },
                { name: 'delta', game: 2 }
            ]
        }
    },
    {
        detail: {
            team: [
                { name: 'echo', game: 1 },
                { name: 'delta', game: 0 },
                { name: 'beta', game: 0 },
                { name: 'gamma', game: 0 },
                { name: 'alpha', game: 0 }
            ]
        }
    },
    {
        detail: {
            team: [
                { name: 'delta', game: 0 },
                { name: 'echo', game: 0 },
                { name: 'beta', game: 0 },
                { name: 'gamma', game: 1 },
                { name: 'alpha', game: 0 }
            ]
        }
    },
    {
        detail: {
            team: [
                { name: 'delta', game: 0 },
                { name: 'echo', game: 0 },
                { name: 'alpha', game: 2 },
                { name: 'gamma', game: 3 },
                { name: 'beta', game: 2 }
            ]
        }
    },
    {
        detail: {
            team: [
                { name: 'delta', game: 0 },
                { name: 'echo', game: 1 },
                { name: 'beta', game: 0 },
                { name: 'gamma', game: 2 },
                { name: 'alpha', game: 0 }
            ]
        }
    }
];


const teams = dataset.map(ds => ds.detail.team);
let z = teams.map(element => {
    return element.map(e => {
        let p = {};
        let n = e.name;
        let c = e.game;
        p[n] = c;
        return p;
    });
});

console.log('z', z);

let nt = [];

z.reduce((c, n, i, a) => {
    let z1 = n.map((i) => {
        console.log(i);
        let entries = Object.entries(i);
        return entries.map((e) => {
          return { label: e[0], data: e[1] };
        });
    });
    return z1;
}, [])

желаемый вывод:

[
    {
        label: 'alpha',
        data: [1, 2, 0, 0, 2, 0]
    },
    {
        label: 'beta',
        data: [1, 2, 0, 0, 2, 0]
    },
    {
        label: 'gamma',
        data: [1, 2, 0, 1, 3, 2]
    },
    {
        label: 'delta',
        data: [ 1, 2, 0, 0, 0, 0]
    },
    {
        label: 'echo',
        data: [1, 2, 1, 0, 0, 1]
    }
]

Я потерял где-то в методе array.reduce для получения результата.

Я предпочтительно ищу решение es6

, любая помощь приветствуется.

Ответы [ 4 ]

0 голосов
/ 25 июня 2018

Другой способ: перебрать набор данных, как он есть, сохраняя результаты в словарном объекте map, а также в массиве возвращаемых результатов.

const dataset = [{detail:{team:[{name:'alpha',game:1},{name:'beta',game:1},{name:'gamma',game:1},{name:'delta',game:1},{name:'echo',game:1}]}},{detail:{team:[{name:'alpha',game:2},{name:'beta',game:2},{name:'echo',game:2},{name:'gamma',game:2},{name:'delta',game:2}]}},{detail:{team:[{name:'echo',game:1},{name:'delta',game:0},{name:'beta',game:0},{name:'gamma',game:0},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'beta',game:0},{name:'gamma',game:1},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'alpha',game:2},{name:'gamma',game:3},{name:'beta',game:2}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:1},{name:'beta',game:0},{name:'gamma',game:2},{name:'alpha',game:0}]}}];
var result = [],
  map = {};
dataset.forEach(a => {
  a.detail.team.forEach(b => {
    if (!(b.name in map)) {
      map[b.name] = [];
      result.push({
        'label': b.name,
        'data': map[b.name]
      })
    }
    map[b.name].push(b.game);
  });
});
console.log(result);
   

Нет необходимости в reduce или map каких-либо массивах здесь.

0 голосов
/ 25 июня 2018

Так что я собираюсь оставить ваш набор данных таким же, но давайте начнем с нуля и создадим некоторый код, чтобы пройти через ваш набор данных и добраться до желаемого результата.

Сначала нам нужноВложите данные:

dataset.map(d => d.detail.team)

Теперь, когда у нас есть команды, давайте сведем их всех к одному массиву

dataset
  .map(object => object.detail.team)
  .reduce((acc, team) => acc.concat(team))

Хорошо, хорошо, теперь у нас есть один большой набор имен и игр.Теперь мы можем довольно легко превратить это в хэш

dataset
  .map(object => object.detail.team)
  .reduce((acc, team) => acc.concat(team))
  .reduce((acc, team) =>{
    acc[team.name] = acc[team.name] || []
    acc[team.name].push(team.game)
    return acc
  }, {})

Теперь у нас есть хэш имен для игр.Вызов Object.entries для этого хеша даст нам пары меток

Object.entries(
  dataset
    .map(object => object.detail.team)
    .reduce((acc, team) => acc.concat(team))
    .reduce((acc, team) =>{
      acc[team.name] = acc[team.name] || []
      acc[team.name].push(team.game)
      return acc
    }, {})
)

Теперь мы можем отобразить эти пары для построения конечного объекта

Object.entries(
  dataset
    .map(object => object.detail.team)
    .reduce((acc, team) => acc.concat(team), [])
    .reduce((acc, team) =>{
      acc[team.name] = acc[team.name] || []
      acc[team.name].push(team.game)
      return acc
    }, {})
)
  .map(([team, games]) => ({ team, games }))

Реальный трюк - сколькоиз этих шагов можно объединить?

ну большинство из них!Мы можем сократить этот цикл до каждого объекта, обращаясь к нему вручную, так как мы знаем структуру, а затем циклически обрабатывая каждый отдельный групповой массив и, наконец, создавая наш хеш.

Object.entries(
  dataset
    .reduce((acc, object) =>{
      object.detail.team.forEach(team =>{
        acc[team.name] = acc[team.name] || []
        acc[team.name].push(team.game)
      })
      return acc
    }, {})
)
  .map(([team, games]) => ({ team, games }))

Дополнительные примечания

Функции стрелок

Мы использовали функции стрелок в этом примере, чтобы максимально придерживаться запроса об использовании ES6. Дополнительную информацию о функциях стрелок можно найти в MDN. По сути, это еще один способ объявления функции

function test(value){ return console.log(value) }
// same as
let test = value => console.log(value)

function add(a, b){ return a + b)
// same as
let add = (a,b) => a + b

Обратите внимание на Array.prototype.forEach()

Теперь выЗаметим, что мы использовали Array.prototype.forEach() в комбинированном примере для манипуляции с аккумулятором.В этом предложении должно быть сказано все, что нам нужно, но для пояснения для тех, кто может не знать, forEach следует использовать, когда вы не хотите возвращаемого значения и хотите только побочные эффекты.В этой ситуации это быстрее, чем пытаться на самом деле что-то вернуть, так как мы не хотим, чтобы мы отбрасывали кучу массивов, которые мы создали, когда конечная цель - изменить только внешний вид аккумулятора.

Фанки-массив, передаваемый в функцию

Ах да, деструктуризация. Опять больше информации можно найти в MDN. По сути, это позволяет нам извлекать значения из объектов или массивов, о которых мы заранее знаем структуру.Примечание: пример предоставлен MDN article

var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20


// Stage 3 proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
0 голосов
/ 25 июня 2018

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

const dataset = [{detail:{team:[{name:'alpha',game:1},{name:'beta',game:1},{name:'gamma',game:1},{name:'delta',game:1},{name:'echo',game:1}]}},{detail:{team:[{name:'alpha',game:2},{name:'beta',game:2},{name:'echo',game:2},{name:'gamma',game:2},{name:'delta',game:2}]}},{detail:{team:[{name:'echo',game:1},{name:'delta',game:0},{name:'beta',game:0},{name:'gamma',game:0},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'beta',game:0},{name:'gamma',game:1},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'alpha',game:2},{name:'gamma',game:3},{name:'beta',game:2}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:1},{name:'beta',game:0},{name:'gamma',game:2},{name:'alpha',game:0}]}}];
const flat = dataset.reduce( (a,b) => a.concat(b.detail.team), []);
let result = [];

for (let element of flat) {

  let match = null;

  for (let e  of result) {
    if (e.label === element.name) {
      match = e;
    }
  }

  if (match) {
    match.data.push(element.game)
  }
  else {
    result.push({
      label : element.name,
      data  : [element.game]
    });
  }

}

console.log(result);
0 голосов
/ 25 июня 2018

Вы можете использовать Array.reduce(), чтобы создать карту, а затем использовать эту карту, чтобы получить желаемый результат.

const dataset = [{detail:{team:[{name:'alpha',game:1},{name:'beta',game:1},{name:'gamma',game:1},{name:'delta',game:1},{name:'echo',game:1}]}},{detail:{team:[{name:'alpha',game:2},{name:'beta',game:2},{name:'echo',game:2},{name:'gamma',game:2},{name:'delta',game:2}]}},{detail:{team:[{name:'echo',game:1},{name:'delta',game:0},{name:'beta',game:0},{name:'gamma',game:0},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'beta',game:0},{name:'gamma',game:1},{name:'alpha',game:0}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:0},{name:'alpha',game:2},{name:'gamma',game:3},{name:'beta',game:2}]}},{detail:{team:[{name:'delta',game:0},{name:'echo',game:1},{name:'beta',game:0},{name:'gamma',game:2},{name:'alpha',game:0}]}}];
var map = dataset.reduce((a,curr)=>{
    curr.detail.team.forEach((e)=> (a[e.name]= (a[e.name] || [])).push(e.game));
    return a;
}, {});
var result =[];

Object.keys(map).forEach((key)=>{
  result.push({
    "label" : key,
    "data" : map[key]
  });
});

console.log(result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...