Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 迭代3个嵌套数组的函数方法_Javascript - Fatal编程技术网

Javascript 迭代3个嵌套数组的函数方法

Javascript 迭代3个嵌套数组的函数方法,javascript,Javascript,我的数据结构如下所示: { sections: [ { pages: [ { questions: [ ], }, ], }, ], } 在我试图获取的问题数组中有数据,并在最后返回最终的一维数组。可以有x个章节,每个章节可以有x个页面,每个页面可以有x个问题 我试图保持代码相对简洁,但也具有可读性,这是我当前的实现: function generateQuestionDa

我的数据结构如下所示:

{
  sections: [
    {
      pages: [
        {
          questions: [

          ],
        },
      ],
    },
  ],
}
在我试图获取的问题数组中有数据,并在最后返回最终的一维数组。可以有
x
个章节,每个章节可以有
x
个页面,每个页面可以有
x
个问题

我试图保持代码相对简洁,但也具有可读性,这是我当前的实现:

function generateQuestionData(survey) {
    let data = [];

    survey.sections.forEach((section) => {
        section.pages.forEach((page) => {
            const newData = page.questions.map(getQuestionDataItem);
            data = [...data, ...newData];
        });
    });

    return data;
}
编辑

有没有一种方法可以在不重新分配
数据的情况下完成同样的事情?因此,一些类似于

function generateQuestionData(survey) {
    return survey.sections.forEach((section) => { // something instead of forEach
        section.pages.forEach((page) => page.questions.map(getQuestionDataItem));
        // data = [...data, ...newData]; no need for this?
    });
}

如果这是有意义的

那么为迭代找一个助手如何:

 function* goOver(array, key, ...keys) {
   for(const el of array) {
    if(keys.length) {
     yield* goOver(el[key] || [], ...keys);
    } else {
     yield el[key];
    }
 }
可以用作:

const result = [...goOver(survey.sections, "pages", "questions")]
   .map(getQuestionDataItem);

关于第二个问题:

有没有一种方法可以在不重新分配数据变量的情况下完成同样的事情

那么:

  data.push(...newData);

您可以使用
reduce
,以便根据
部分
page
向以下类似人员展示真正做某事的意图:

private generateQuestionData = (survey) =>
    survey.sections.reduce((data, section) =>
        [
          ...data,
          ...section.pages.reduce((pageData, page) =>
              [
                ...pageData,
                ...page.questions.map(getQuestionDataItem)
              ],
              []
          )
        ],
        []
    );
代码缩进/格式肯定可以优化

const data = {
  sections: [
    {
      pages: [
        {
          questions: [
            "hello",
            "world"
          ],
        },
        {
          questions: [
            "foo",
            "bar"
          ]
        }
      ],
    },
  ],
};


const get = (...pathKeys) => o => pathKeys.reduce((o,k ) => o[k], o);
const flatten = (arrays) => [].concat.apply([], arrays);
const result = flatten(get("sections")(data).map(s => get("pages")(s).map(get("questions"))));
console.log(flatten(flatten(result)));
请注意,可以使用Flattedeep函数简化末端的展平

在“伪代码”中,我会用
compose
是从左到右的合成,map是
fn=>arr=>arr.map(fn)


我不确定你能为此做些什么。。。。而且不确定reduce如何使其更具可读性。@epascarello bummer:/我在想reduce可以摆脱嵌套的
forEach
loops您可以在外部使用reduce,但您所做的只是转换一些代码。无论您选择哪种方式,您都需要3个循环do@epascarello我更新了问题,,我想我问错了
compose(
  get("section"),
  map(compose(get("pages"), map(get("questions")))),
  flattenDeep,
);