我们如何减少嵌套数组?

时间:2019-07-11 05:06:31

标签: javascript arrays object ecmascript-6 lodash

用标记映射学生证的我的对象如下:

[
    {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 个答案:

答案 0 :(得分:2)

您可以使用forEach循环。

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);

答案 1 :(得分:2)

没有Lodash

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)

使用Lodash

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 :(得分:0)

另一种使用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);

答案 3 :(得分:0)

使用lodash,您可以使用_.flatMap()map将学生的标记迭代为成对的[key,value]。要生成密钥,您可以使用_.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>

相关问题