2

Im new to programming, I have an assignment that asks to create a 2d-array from a 1d array. I came up with this (no help from any outside sources because it takes away the learning experience). It works for our professors test inputs, I was just wondering is this an ugly/inefficient solution.

function twoDArray(arr, lenSubArray) {
    var newArr = []; 
    var placeHolder = 0; 
    var leftOver = 0; 
    for (var i = 1; i < arr.length + 1; i++) {
        /* if i is a multiple of the specified sub-array size 
           then add the elements from placeHolder to i
        */
        if (i % lenSubArray === 0) {
            newArr.push(arr.slice(placeHolder, i)); 
            placeHolder += lenSubArray; 
            leftOver++; // tells us how many sub-arrays were created
        }
    }
    /* if original array is not divisible by the length of the specified sub-array
       then there will be left over values. Retrieve these values and create an 
       array out of them and add them to the 2d array.
    */
    if (!(arr.length % lenSubArray === 0)) {
         /* sub-array count multiplied by the length of each 
            sub-array gives us the right index to retrieve remaining values
        */
        leftOver = (leftOver * lenSubArray);
        newArr.push(arr.slice(leftOver))
    }

    return newArr; 
}

Test input: twoDArray([1, 2, 3, 4, 5], 3) output would be: [[1, 2, 3], [4, 5]]

2
  • please add an example of the input array and the wanted output array. Commented Aug 20, 2016 at 18:23
  • concat would give you a lot cleaner code. Check out this stackoverflow.com/questions/14824283/… Commented Aug 20, 2016 at 18:25

3 Answers 3

2

you're way too complicated:

  • create a result-array
  • push slices from i to i+lenSubArray
  • increment i by lenSubArray

and slice is smart enough to properly handle the end of the Array

function twoDArray(arr, lenSubArray) {
  var i = 0, result = [];
  while(i < arr.length)
    result.push( arr.slice(i, i+=lenSubArray) );
  return result;  
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a ton, I had no idea slice() could handle the end of the array.
1

You could use Array#reduce and build new arrays based on the index.

function twoDArray(array, length) {
    return array.reduce(function (r, a, i) {
        i % length ? r[r.length - 1].push(a) : r.push([a]);
        return r;
    }, []);
}

console.log(twoDArray([1, 2, 3, 4, 5], 3));

Comments

0

You do not need to iterate over an array. You can use Array.prototype.slice function instead.

function twoDArray(a, b){
    return (Array(Math.ceil(a.length / b)) + '').split(',').map(function(c, d){
        return a.slice(b * d, b * (d + 1));
    });
}

Here is how you call it

var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
console.log(twoDArray(a, 3));
// Output:
// [
//   [1, 2, 3],
//   [4, 5, 6],
//   [7, 8, 9],
//   [10, 11, 12]
// ]

4 Comments

oh, that's not nice: if you calculate the length as Math.ceil(a.length/b) you don't have to patch the result by filtering, and instead of (Array(len)+'').split(',').map(fn) you can use Array(len).fill(0).map(fn) or Array.from({ length: len }, fn)
@Thomas. Using Math.ceil is bad practice, it is better to convert second argument to integer and then filter array is necessary. Also, Array.prototype.fill is not implemented in some versions of Node.js.
why do you consider Math.ceil as bad, even worse, than creating two unnecessary Arrays and calling a filter-function on every element of the result?
@Thomas. Because Math.ceil can produce NaN values if some error uccurs which can cause problems later. But anyway, I edited answer.

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.