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

时间:2018-05-09 19:57:47

标签: javascript arrays multidimensional-array nested-loops

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

功能:

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"]

1 个答案:

答案 0 :(得分:2)

您使用' map'

一方面,你正在使用地图'最好使用其他数组方法,例如' forEach'或者'减少'。该函数传入了地图'方法应该返回新数组的元素。您正在使用地图'方法只是迭代数组而不捕获结果。

示例#1

以下是您的' matchIDs'的略微修改版本。功能。第一个缩小使页面变平以制作单个问题列表。第二个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}`;
  });
}

Runnable片段



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