0

In an app that's being developed there is a use case whereby dates need to be generated from an array of months and another array of years. Here is an example of representative data in those arrays:

const months= ["1", "4", "7", "9"];
const years = ["2021", "2022", "2027"];

The necessary result is the first day of each month + year combination, like so:

const dates = [
"1/1/2021", "4/1/2021", "7/1/2021", "9/1/2021",
"1/1/2022", "4/1/2022", "7/1/2022", "9/1/2022",
"1/1/2027", "4/1/2027", "7/1/2027", "9/1/2027"
];

The way I would do this in T-SQL is as follows -

select *
into #months
from
(
    values
    (1),
    (4),
    (7),
    (9)
) d (month);

select *
into #years
from
(
    values
    (2021),
    (2022),
    (2027)
) d (year);

select [dates] = datefromparts(year, month, 1)
from #months
cross join #years;

Output:
enter image description here

So, is there a cross join equivalent in Javascript? I'd rather use a concise approach like that rather than nested .forEach() statements.

2 Answers 2

1

You can build that result by using Array#map() calls together, like so:

const months= ["1", "4", "7", "9"];
const years = ["2021", "2022", "2027"];
const dates = years.flatMap(year => {
  return months.map(month => `${month}/1/${year}`);
});
console.log(dates);

flatMap() is conceptually the same as map() and flat() together (but more performant).

const months= ["1", "4", "7", "9"];
const years = ["2021", "2022", "2027"];
const dates = years.map(year => {
  return months.map(month => `${month}/1/${year}`);
}).flat();
console.log(dates);

Sign up to request clarification or add additional context in comments.

2 Comments

I don't see any difference between the support tables for flat and flatMap. Obviously if you need to support older browsers, you can polyfill either of them or use a reduce-concat solution. But I'm not sure there's any good reason for the .flat solution when .flatMap is clearer and more performant.
You're right, thanks. I hoped it would be helpful for understanding .flatMap, edited to explain that better.
0

We can write a fairly simple crossproduct function that takes two arrays and a function and combines each pair of their product with the function.

It might look like this:

const crossproduct = (xs = [], ys = [], fn = (x, y) => [x, y]) =>
  xs .flatMap ((x) => ys .map ((y) => fn(x, y)))

const months= ["1", "4", "7", "9"]
const years = ["2021", "2022", "2027"]

const dates = crossproduct (years, months, (y, m) => `${m}/1/${y}`)

console .log (dates)
.as-console-wrapper {max-height: 100% !important; top: 0}

Note that crossproduct has a default function that just returns an array containing the two values. This is often useful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.