javascript - 在没有太多嵌套循环的情况下在多维数组中查找匹配元素?

标签 javascript arrays multidimensional-array nested-loops

我有一个包含三层嵌套的数组和一个一维对象。我需要比较两者以找到匹配的 ID,并将它们成对放入一个新数组中。我只是在这里使用 map 方法,但也许有更有效的方法来做到这一点?我想过使用 filter 方法,但我认为它在这种情况下行不通。

函数:

const getMatchingIDs = function (pages, storedOBJ)  {
    const arr = []

    pages.map((page)=> {
        return page.questions.map((q)=>{
            const questionText = q.questionText

            return Object.keys(storedOBJ).map((key) => {
                const answerIndex = storedOBJ[key]

                if (typeof answerIndex !== 'undefined' && questionText === key) {
                    const answerID = q.answers[answerIndex].id
                    arr.push( q.id +  ':' + answerID)
                }
            })
        })
    })
    return arr
}

数组和对象:

const pages = [
{
    questions: [
        {
            id: 987,
            questionText: 'Some Question',
            answers: [
                {
                    id: 154
                },
                {
                    id: 232
                },
                {
                    id: 312
                }
            ]
        },
        {
            id: 324,
            questionText: 'Another Question',
            answers: [
                {
                    id: 154
                },
                {
                    id: 232
                },
                {
                    id: 312
                }
            ]
        },
        {
            id: 467,
            questionText: 'Last Question',
            answers: [
                {
                    id: 154
                },
                {
                    id: 232
                },
                {
                    id: 312
                }
            ]
            }
        ]
    }
]

const storedOBJ = {
    'Some Question': 0,
    'Last Question': 0,
    'Another Question': 2
}

运行 getMatchingIDs(pages, storedOBJ) 应该返回 ["987:154", "324:312", "467:154"]

最佳答案

您对“ map ”的使用

因此,一方面,您使用的是“map”方法,而使用其他数组方法(例如“forEach”或“reduce”)会更好。传递给“map”方法的函数应该为新数组返回一个元素。您使用 'map' 方法只是为了迭代数组而不捕获结果。

示例#1

这是您的“matchIDs”函数的略微修改版本。第一个 reduce 将页面展平以制作一个问题列表。第二个 reduce 生成你的匹配项,并跳过答案索引未定义的条件。

function matchIDs(pages, answerMap) {
  const questions = pages.reduce((questions, page) => { return questions.concat(page.questions) }, []);

  return questions.reduce((matches, question) => {
    const answerIndex = answerMap[question.questionText];
    if(typeof answerIndex != 'undefined') matches.push(`${question.id}:${question.answers[answerIndex].id}`);
    return matches;
  }, []);
}

示例#2

在您的示例数据中,您只有一页,而且您的所有答案索引都是有效的。如果您可以做出这些假设,您可以进一步简化:

function matchIDs(questions, answerMap) {
  return questions.map(question => {
    const answerIndex = answerMap[question.questionText];
    return `${question.id}:${question.answers[answerIndex].id}`;
  });
}

可运行代码段

const pages = [
  {
    questions: [
      {
        id: 987,
        questionText: 'Some Question',
        answers: [
          {
            id: 154
          },
          {
            id: 232
          },
          {
            id: 312
          }
        ]
      },
      {
        id: 324,
        questionText: 'Another Question',
        answers: [
          {
            id: 154
          },
          {
            id: 232
          },
          {
            id: 312
          }
        ]
      },
      {
        id: 467,
        questionText: 'Last Question',
        answers: [
          {
            id: 154
          },
          {
            id: 232
          },
          {
            id: 312
          }
        ]
      }
    ]
  }
];

const storedOBJ = {
  'Some Question': 0,
  'Last Question': 0,
  'Another Question': 2
};

function matchIDs(pages, answerMap) {
  const questions = pages.reduce((questions, page) => { return questions.concat(page.questions) }, []);

  return questions.reduce((matches, question) => {
    const answerIndex = answerMap[question.questionText];
    if(typeof answerIndex != 'undefined') matches.push(`${question.id}:${question.answers[answerIndex].id}`);
    return matches;
  }, []);
}

function matchIDsAlt(questions, answerMap) {
  return questions.map(question => {
    const answerIndex = answerMap[question.questionText];
    return `${question.id}:${question.answers[answerIndex].id}`;
  });
}

console.log(matchIDs(pages, storedOBJ));
console.log(matchIDsAlt(pages[0].questions, storedOBJ));

关于javascript - 在没有太多嵌套循环的情况下在多维数组中查找匹配元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50261120/

相关文章:

javascript - 如何将其转换为影响所有值的全局 JavaScript 函数

php - 按键的值过滤一个数组,为每个键的值将其重组为一个子数组

java - 如何实现一个多维数组,其中第一维随着添加更多第二维数组而改变大小?

javascript - 我们如何在 nodeJS 中使用 module.exports 返回函数?

javascript - Backbone.js 和 jquery 将点击事件绑定(bind)到 View 函数

javascript - 在 map 上用实线和虚线标记绘制路径

python - 按内部数组的长度对 numpy 数组的 numpy 数组进行排序

java - 如何将一维数组转换为二维数组?

Java,如何检查两个二维数组是否包含相同的值

javascript - 使用 JavaScript 加载 HTML 模板