Search code examples
javascriptlodashprototype

Merge and multiply arrays into one single array


I need to create one single array from 3 arrays,

I already implemented the logic and it's working but i think with Array.prototype i can achieve the same with better performance

let classrooms = [
    1,
    2
]
let modules = [
    5,
    6
]

let weeks = [
   7,
   8
]

let avalArray = [];
classrooms.forEach(classroomId => {
        modules.forEach(moduleId => {
            weeks.forEach(week => {
                avalArray.push({
                    classroomId: classroomId,
                    moduleId: moduleId,
                    week: week
                });
            });
        });
    }); 

This is the expected output:

[ { classroomId: 1, moduleId: 5, week: 7 },
  { classroomId: 1, moduleId: 5, week: 8 },
  { classroomId: 1, moduleId: 6, week: 7 },
  { classroomId: 1, moduleId: 6, week: 8 },
  { classroomId: 2, moduleId: 5, week: 7 },
  { classroomId: 2, moduleId: 5, week: 8 },
  { classroomId: 2, moduleId: 6, week: 7 },
  { classroomId: 2, moduleId: 6, week: 8 } ] ```

Solution

  • There was a request some time ago for the cartesian product back in #852 (January 2015!). As you see, it's not implemented.

    As the others said, performing a simple loop without external arrays will definitely be faster. To be sure: just benchmark it. I've prepared a simple suite on perf.link and here are the results:

    for-loop:         175us
    for-of-loop:      175us
    forEach:          290us
    map-map-map-flat: 465us
    flatMap:          5635us
    

    Exact numbers are not important here, but here's one takeaway: for-of loop (not transpiled!) is one of the fastest and still very elegant:

    const result = [];
    for (const classroomId of classrooms)
      for (const moduleId of modules)
        for (const week of weeks)
          result.push({classroomId, moduleId, week});