как назначить объект в объекте - PullRequest
0 голосов
/ 20 ноября 2018

как назначить объект в объекте и отфильтровать значение, которое проходит и терпит неудачу;

ввод:

    [
      {
        name: 'John',
        score: 90,
        time: 'evening'
      },
      {
        name: 'Doni',
        score: 68,
        time: 'morning'
      },
      {
        name: 'Jiu',
        score: 50,
        time: 'evening'
      },
      {
        name: 'Shin',
        score: 92,
        time: 'morning'
      },
    ];

и я хочу вывод, как это:

{
  "evening": {
    "pass": [
      {
        "name": "John",
        "score": 90
      }
    ],
    "fail": [
      {
        "name": "jiu",
        "score": 50
      }
    ]
  },
  "morning": {
    "pass": [
      {
        "name": "Shin",
        "score": 92
      }
    ],
    "fail": [
      {
        "name": "Doni",
        "score": 68
      }
    ]
  }
}

нужно ли для этого использовать Object.assign?а сколько петли мы используем для этого ??я люблю знать, как добавить еще одну строку в объект, кроме этого выхода, спасибо

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Есть много способов сделать это.Самым простым, вероятно, является создание базового объекта, представляющего ваши пустые результаты.Затем переберите студентов и заполните массивы:

let students = [{name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];

// Empty case
let base =  {
        "evening": {"pass": [], "fail": []},
        "morning": {"pass": [], "fail": []}
}

const PASSING = 70

students.forEach(({name, score, time}) => {
    let key = score >= PASSING ? 'pass' : 'fail'
    base[time][key].push({name, score})
})
console.log(base)

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

РЕДАКТИРОВАТЬ на основе комментариев:

Чтобы поддерживать произвольное время, вы можете просто создать время на объекте так, как вы его нашли.reduce() хорошо для этого, но вы также можете использовать обычный цикл.Например, с добавленным afternoon временем:

let students = [{name: 'Mark',score: 95,time: 'afternoon'}, {name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];

const PASSING = 70

let result = students.reduce((obj, {name, score, time}) => {
    if (!obj[time]) obj[time] = {'pass': [], 'fail': [] }

    let key = score >= PASSING ? 'pass' : 'fail'
    obj[time][key].push({name, score})

    return obj
}, {})


console.log(result)
0 голосов
/ 20 ноября 2018

Вы можете сделать что-то вроде этого:

const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];

const grp = (d, p) => d.reduce((r,c) => (r[c[p]] = [...r[c[p]] || [], c], r), {})
const grpV = (d, rng) => d.reduce((r,{name, score}) => {
  let key = score > rng ? 'pass' : 'fail'
  r[key] = [...r[key] || [], {name, score}]
  return r
}, {})

const r = Object.entries(grp(data, 'time')).map(([k,v]) => ({[k]: grpV(v, 75)}))

console.log(r)

Идея состоит в том, чтобы группа 2 раза по одному на time и вторая по score.

grp: функция для группировки по свойству (в данном случае «время»), которое возвращает объект с 2 свойствами: evening и morning, каждое из которых представляет собой массив, содержащий классы.

grpV: функция для группировки по значению (в данном случае 75), которая возвращает объект с 2 свойствами: pass и fail, каждое из которых является массивом, содержащим классы .

В конце концов, когда у нас есть те tools, которые мы говорим ... дайте мне entries сгруппированного по time объекта и для каждой из групп ... сгруппируйте по баллам.

Вот как это может выглядеть, если мы используем lodash:

const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];

const partition = (x, p) => _(x)
  .partition(y => y.score > p)
  .map((x,i) => ({ [i==0 ? 'pass': 'fail']: _.omit(x[0], 'time')}))
  .value()

const r = _(data)
  .groupBy('time')
  .mapValues(x => partition(x, 75))
  .value()

console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Добавление его в качестве примера, поскольку оно помогает в некоторой степени понять, что делает пример ES6.

0 голосов
/ 20 ноября 2018

Я уверен, что есть более элегантные способы сделать это.Но этот, вероятно, является одним из самых простых, удобных для новичков способов.

Я перебираю входной массив, проверяю наличие значений .time в качестве ключей на объекте output исоздайте ключи pass и fail.Затем сравните .score с passingScore и вставьте в него необходимые данные.

Должно быть достаточно легко понять, как только вы увидите и попробуете следующий код:

const data =   [
      {name: 'John',score: 90, time: 'evening'},
      {name: 'Doni',score: 68, time: 'morning'},
      {name: 'Jiu',score: 50, time: 'evening'},
      {name: 'Shin',score: 92, time: 'morning'},
      {name: 'Fubar',score: 75, time: 'noon'},
    ];
    
    
function formatData(data){
   const passingScore = 75;
   const output = {};

   data.forEach(function(item){
      if(!output[item.time]) output[item.time] = {pass: [], fail: []};

      const stud = { name: item.name, score: item.score };
        
      if(item.score >= passingScore) output[item.time]['pass'].push(stud)
      else output[item.time]['fail'].push(stud)  
   });

   return output;
}

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