2

I want to create a multi-dimensional array like this using Lodash or vanilla JS:

[
  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
  etc
]

This is a simplistic example since I want this pattern to continue up to 1,000,000 but for demonstration 1 to 20 is fine.

Any ideas? I've tried _.range(20) so far but I need this Array to be multi-dimensional. Thanks

2
  • What happened when you tried _.range(20)? Perhaps you'd then be interested in _.chunk() Commented Nov 20, 2018 at 23:54
  • 1
    Pure JS: Array.from(new Array(30)).map((_, i) => i + 1).reduce((acc, v) => v % 10 === 1 ? [...acc, [v]] : (acc[Math.floor((v - 1) / 10)].push(v), acc), []) Commented Nov 20, 2018 at 23:58

4 Answers 4

6

With lodash you can use chunk:

const result = _.chunk(_.range(1, 21), 10);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

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

2 Comments

Just a minor correction... OP's arrays start at 1
Upvote! First thing I though about when I read the question and then realized you already wrote it :)
5

Using nested native Array#from()

const 
   limit = 100,
   fr = Array.from;

const res = fr({ length:limit/10 }, (_,i) => fr({ length:10 }, (_,j) => i*10 + j+1 ));

console.log(res)

5 Comments

Array#from() 👈 spot the Java dev ;-)
I know OP doesn't mention, but what if the limit isn't a multiple of 10, say 25? Slider's answer handles that case via chunking
@Phil right...I assumed even 10's based on 20 and 1,000,000
It's not as pretty, but you could have something like {length:Math.min(10, limit-(i*10))} in the inside loop to handle non-even groupings.
@Akrion me too...never noticed that range generator example until I saw it in yours
3

Looking at the ES6 Array.from documentation you can see a range generator function:

const range = (start, stop, step) => Array.from({ length: (stop -
start) / step }, (_, i) => start + (i * step));

So with that in mind you could generate the range via:

range(1, 21, 1)  // account for the 0 with the 21 otherwise you get 1-19

Then all that is missing is the chunk function:

const range = (start, stop, step) => Array.from({ length: (stop - start) / step }, (_, i) => start + (i * step));
const chunkBy = (arr, by=2) => arr.reduce((r,c,i) => (i%by==0 ? r.push([c]) : r[r.length-1] = [...r[r.length-1], c], r), [])

console.log(chunkBy(range(1,21,1), 10))

The chunkBy uses Array.reduce & the % operator to chunk the data.

1 Comment

And you wrote a mini lodash :D
3

With vanilla javascript:

x = []
for (i=1; i<=20; i=i+10) {
    y = []
    for (j=0; j<10; j++) {
        y.push(i + j)
    }
    x.push(y)
}
console.log(x)

For anyone who's interested, I time clocked these answers and this is the fastest. Using 1 million entries, this clocks at .100 seconds. Lodash chunk clocks close behind at .110s. Array.from lags behind at .254s.

1 Comment

@Phil hah, fixed... and time-clocked

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.