React / ES6 уменьшить объект - PullRequest
0 голосов
/ 09 марта 2019

У меня есть следующий объект, который содержит тренировки для определенных дней:

{
  "2019-03-02": [
    {
        "id": 1,
        "workout_day": "2019-03-02",
        "title": "Swimming",
        "description": "",
        "completed": true,
        "points": 5
    },
    {
        "id": 2,
        "workout_day": "2019-03-02",
        "title": "Running",
        "description": "",
        "completed": false,
        "points": 0
    },
    {
        "id": 3,
        "workout_day": "2019-03-02",
        "title": "Rowing",
        "description": "",
        "completed": true,
        "points": 3
    },
  ],
 "2019-03-05": [...]
}

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

{
  "2019-03-02": {
    "workouts": 3,
    "workouts_completed": 2,
    "total_points": 8
  },
  "2019-03-05: {...}
}

Однако я полностью застрял на данный момент.Спасибо за помощь!

Ответы [ 6 ]

1 голос
/ 09 марта 2019

Предполагая, что у вас есть объект, который содержит тренировки в течение определенных дней в объекте с именем json, вы можете использовать Object.keys() для перебора всех ключей.Тогда вы можете map пройти через это и получать тренировки для одного конкретного дня за раз.Затем вы можете использовать это для создания объекта на каждый день.Для вычисления таких вещей, как totalPoints, вы будете использовать reduce для суммирования общего количества баллов.

Object.keys(json).map(key => {
    return {
        [key]: {
            workoutsCompleted: json[key].length,
            totalPoints: json[key].reduce((accum, workout) => accum + workout.points, 0)
        }
    };
});
1 голос
/ 09 марта 2019

Это делает работу.

Я использовал Array.prototype.reduce и деструктурируется со значениями по умолчанию.

var data = {
  "2019-03-02": [{
      "id": 1,
      "workout_day": "2019-03-02",
      "title": "Swimming",
      "description": "",
      "completed": true,
      "points": 5
    }, {
      "id": 2,
      "workout_day": "2019-03-02",
      "title": "Running",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 3,
      "workout_day": "2019-03-02",
      "title": "Rowing",
      "description": "",
      "completed": true,
      "points": 3
    },
  ],
  "2019-03-05": [{
      "id": 1,
      "workout_day": "2019-03-02",
      "title": "Swimming",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 2,
      "workout_day": "2019-03-02",
      "title": "Running",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 3,
      "workout_day": "2019-03-02",
      "title": "Rowing",
      "description": "",
      "completed": true,
      "points": 8
    },
  ]
};

var result = {};

for (let key in data) {
  result[key] = data[key].reduce(({
        workouts = 0,
        workouts_completed = 0,
        total_points = 0
      }, currentValue) => {
      return {
        workouts: workouts + 1,
        workouts_completed: currentValue.completed ? workouts_completed + 1 : workouts_completed,
        total_points: total_points + currentValue.points
      };
    }, {});
}

console.log(result);
1 голос
/ 09 марта 2019

У вас есть несколько решений для достижения этой цели.Вот тот, который в совокупности Object.entries + Array.reduce.

Object.entries(input).reduce((acc, [date, workouts]) => {
  const completed = workouts.filter(workout => workout.completed);

  return {
    ...acc,
    [date]: {
      workouts: workouts.length,
      workouts_completed: completed.length,
      total_points: completed.reduce((acc, workout) => acc + workout.points, 0),
    }
  };
}, {});

Обратите внимание, что Object.entries доступен не во всех основных браузерах.

1 голос
/ 09 марта 2019

Это уменьшит ваши данные до того, которое вы хотите преобразовать в

const data = {
  '2019-03-02': [{
      id: 1,
      workout_day: '2019-03-02',
      title: 'Swimming',
      description: '',
      completed: true,
      points: 5
    },
    {
      id: 2,
      workout_day: '2019-03-02',
      title: 'Running',
      description: '',
      completed: false,
      points: 0
    },
    {
      id: 3,
      workout_day: '2019-03-02',
      title: 'Rowing',
      description: '',
      completed: true,
      points: 3
    }
  ],
  '2019-03-03': [{
      id: 1,
      workout_day: '2019-03-02',
      title: 'Swimming',
      description: '',
      completed: true,
      points: 7
    },
    {
      id: 2,
      workout_day: '2019-03-02',
      title: 'Running',
      description: '',
      completed: false,
      points: 0
    },
    {
      id: 3,
      workout_day: '2019-03-02',
      title: 'Rowing',
      description: '',
      completed: false,
      points: 3
    }
  ]
}

const reducedData = Object.keys(data).reduce((acc, key) => {
  acc[key] = {
    workouts: data[key].length,
    workouts_completed: data[key].reduce((acc, item) => {
      if (item.completed) return acc + 1
      return acc
    }, 0),
    total_points: data[key].reduce((acc, item) => {
      return acc + item.points
    }, 0)
  }
  return acc
}, {})

console.log(reducedData)
0 голосов
/ 09 марта 2019
const data = {
  "2019-03-02": [
    {
        "id": 1,
        "workout_day": "2019-03-02",
        "title": "Swimming",
        "description": "",
        "completed": true,
        "points": 5
    },
    {
        "id": 2,
        "workout_day": "2019-03-02",
        "title": "Running",
        "description": "",
        "completed": false,
        "points": 0
    },
    {
        "id": 3,
        "workout_day": "2019-03-02",
        "title": "Rowing",
        "description": "",
        "completed": true,
        "points": 3
    },
  ],
 "2019-03-05": []
};

function makeReport (report, workout) {
  return {
    workouts: report.workouts + 1,
    workouts_completed: workout.completed ? report.workouts_completed + 1 : report.workouts_completed,
    total_points: report.total_points + workout.points
  };
}

const out = Object.entries(data).reduce(function (report, [date, workouts]) {
  return {
    ...report,
    [date]: workouts.reduce(makeReport, { workouts: 0, workouts_completed: 0, total_points: 0 })
  };
}, {});

console.log(out);

который регистрирует:

{ '2019-03-02': { workouts: 3, workouts_completed: 2, total_points: 8 },
  '2019-03-05': { workouts: 0, workouts_completed: 0, total_points: 0 } }
0 голосов
/ 09 марта 2019
 const result = {};

 for(const [workout_day, entries] of Object.entries(input)) {
   result[workout_day] = { 
     workouts: entries.length,
     workouts_completed: entries.reduce((acc, e) => acc + e.completed, 0),
     total_points: entries.reduce((acc, e) => acc + e.points, 0),
  };
}

Object.entries очень полезно для отображения объектов.

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