Как мы уменьшаем вложенные массивы? - PullRequest
3 голосов
/ 11 июля 2019

Мой объект, который отображает студенческий идентификатор с отметками, выглядит следующим образом:

[
    {id: 111, marks: [{sub: 'eng', mark: 90}, {sub: 'maths', mark: 20}]},
    {id: 222},
    {id: 333, marks: []},
    {id: 444, marks: [{sub: 'eng', mark: 70}]}
]

Я бы хотел уменьшить его следующим образом:

{
    marks[0]: "0:eng:90", // studentIndex:subject_name:mark
    marks[1]: "0:maths:20",
    marks[2]: "3:eng:70"
}

В приведенном выше результате ключ - "marks []", а значение - строка, которая представляет собой сцепление studentIndex, субъекта и оценки. Таким образом, здесь 0: eng: 90 означает, что студент с индексом 0 набрал 90 баллов по предмету английского

Я использую lodash, и я попробовал следующее:

reduce(studentList, (acc, student, studentIndex) => {
    map(get(student, 'marks'), (marks) => {
      acc[`marks[${keys(acc).length}]`] = `${studentIndex}:${marks.sub}:${marks.mark}`;
    });
    return acc;
  }, {});

Есть ли другой лучший способ сделать это?

Ответы [ 4 ]

2 голосов
/ 11 июля 2019

без Лодаша

var studentList = [{"id":111,"marks":[{"sub":"eng","mark":90},{"sub":"maths","mark":20}]},{"id":222},{"id":333,"marks":[]},{"id":444,"marks":[{"sub":"eng","mark":70}]}]

var result = studentList.reduce((acc, student, studentIndex) => {
  (student.marks || []).map((marks) => {
    acc[`marks[${Object.keys(acc).length}]`] = `${studentIndex}:${marks.sub}:${marks.mark}`;
  });
  return acc;
}, {});

console.log(result)

С Лодашем

var studentList = [{"id":111,"marks":[{"sub":"eng","mark":90},{"sub":"maths","mark":20}]},{"id":222},{"id":333,"marks":[]},{"id":444,"marks":[{"sub":"eng","mark":70}]}]

var result = _.reduce(studentList, (acc, student, studentIndex) => {
  _.map(student.marks || [], (marks) => {
    acc[`marks[${_.keys(acc).length}]`] = `${studentIndex}:${marks.sub}:${marks.mark}`;
  });
  return acc;
}, {});

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
2 голосов
/ 11 июля 2019

Вы можете использовать forEach loop.

const input = [
    {id: 111, marks: [{sub: 'eng', mark: 90}, {sub: 'maths', mark: 20}]},
    {id: 222, marks: []},
    {id: 333, marks: []},
    {id: 444, marks: [{sub: 'eng', mark: 70}]}
];

const output = [];

input.forEach(({marks}, i) =>  {
    marks.forEach(({sub, mark}) => {
        output.push(`${i}:${sub}:${mark}`);
    });
});

console.log(output);

- Правка -

const input = [
    {id: 111, marks: [{sub: 'eng', mark: 90}, {sub: 'maths', mark: 20}]},
    {id: 222},
    {id: 333, marks: []},
    {id: 444, marks: [{sub: 'eng', mark: 70}]}
];

const output = {};
let count = 0;

input.forEach((obj, i) =>  {
    if(obj.hasOwnProperty("marks")) {
        obj.marks.forEach(({sub, mark}) => {
            output[`marks[${count}]`] = `${i}:${sub}:${mark}`;
            count++;
        });
    }
});

console.log(output);
0 голосов
/ 11 июля 2019

С помощью lodash вы можете перебирать учащихся с _.flatMap() и отображать оценки учеников на пары [ключ, значение]. Для генерации ключа вы можете использовать _.uniqueId(). Конечным результатом будет массив пар, который можно преобразовать в объект с помощью _.fromPairs():

const studentList = [{"id":111,"marks":[{"sub":"eng","mark":90},{"sub":"maths","mark":20}]},{"id":222},{"id":333,"marks":[]},{"id":444,"marks":[{"sub":"eng","mark":70}]}]

const result = _.fromPairs( // convert the array to an object
  _.flatMap(studentList, ({ marks }, sIndex) => // iterate the students
    _.map(marks, ({ sub, mark }) => [ // iterate the marks
      `marks${_.uniqueId() - 1}`, // generate the key
      `${sIndex}:${sub}:${mark}` // generate the value
    ])
  )
)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
0 голосов
/ 11 июля 2019

Еще один короткий путь без lodash с использованием map:

var studentList = [
    {id: 111, marks: [{sub: 'eng', mark: 90}, {sub: 'maths', mark: 20}]},
    {id: 222},
    {id: 333, marks: []},
    {id: 444, marks: [{sub: 'eng', mark: 70}]}
];

var ac = {};
studentList.map((student, i) => {
  if (student.marks && student.marks.length)
    student.marks.map(m => ac[`marks[${Object.keys(ac).length}]`] = `${i}:${m.sub}:${m.mark}`);
});

console.log(ac);
...