0

So I have 2 separate 2D array, they are not necessarily the same length, and I want to make an object for each. I made this:

var obj1 = {},
    obj2 = {};

    for (var i=0; i<arr1.length; i++) {

      obj1[arr1[i][1]] = arr1[i][0];

    }  

    for (var j=0; j<arr2.length; j++) {

      obj2[arr2[j][1]] = arr2[j][0];

    }

My question is if there is a way to make this with only one loop. Thanks!

Chantun
  • 81
  • 1
  • 7
  • See this Q http://stackoverflow.com/questions/4215737/convert-array-to-object – benahm Mar 21 '17 at 12:24
  • 3
    How big are arr1 and arr2? It might not be worth to do any optimization at all here... – x-ray Mar 21 '17 at 12:25
  • 1
    It's not getting more efficient when you use only one loop. You'd need to use a different *algorithm* – Bergi Mar 21 '17 at 12:25
  • I agree with @Bergi, no matter how much loops you use, there's still the same number of operations. – eur00t Mar 21 '17 at 12:32
  • @x-ray it depends on the implementation, i don't use ifs in my answer. Though technically I'm using 2 loops, the number of iterations is optimized. – eur00t Mar 21 '17 at 12:58

5 Answers5

3

You could try something like this:

var obj1 = {},
    obj2 = {},
    length = Math.max(arr1.length, arr2.length);  // get max array length

for (var i = 0; i < length; i++) {                // loop max array length

  if (i < arr1.length) {                          // do check for arr1
    obj1[arr1[i][1]] = arr1[i][0];   
  }

  if (i < arr2.length) {                          // do check for arr2
    obj2[arr2[i][1]] = arr2[i][0];
  }
}

As pointed out, this may be less efficient than 2 separate loops,

Although it also may be more efficient

Pete
  • 57,112
  • 28
  • 117
  • 166
2

What you really want here is a function abstraction that removes the duplication. There is nothing to make this more efficient (if you meant time complexity, not developer efficiency):

function arrToObj(arr) {
    var obj = {};
    for (var i=0; i<arr.length; i++) {
        obj[arr[i][1]] = arr[i][0];
    }  
    return obj;
}
var obj1 = arrToObj(arr1),
    obj2 = arrToObj(arr2);

The loop is still executed twice, but it's only written once.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • You, sir, are the real MVP. I expressed myself wrong. I should have written "simplicity" and not "efficiency". This is exactly what I meant. Thanks. – Chantun Mar 21 '17 at 23:15
0

Something like this should work:

var obj1 = {},
    obj2 = {};

for (let i = 0; i < arr1.length && i < arr2.length; i++) {

    obj1[arr1[i][1]] = arr1[i][0];
    obj2[arr2[i][1]] = arr2[i][0];
}

if (arr1.length > arr2.length) {
    for (let i = arr2.length; i < arr1.length; i++) {
        obj1[arr1[i][1]] = arr1[i][0];
    }
}

if (arr2.length > arr1.length) {
    for (let i = arr1.length; i < arr2.length; i++) {
        obj2[arr2[i][1]] = arr2[i][0];
    }
}
eur00t
  • 1,400
  • 10
  • 7
0

Inspired by Pete's and eur00t's answers, I suggest this one:

var commonLength = Math.min(arr1.length, arr2.length);

for (var i = 0; i < commonLength; i++) {
    obj1[arr1[i][1]] = arr1[i][0];
    obj2[arr2[i][1]] = arr2[i][0];
}

for (var i = commonLength; i < arr1.length; i++) {
    obj1[arr1[i][1]] = arr1[i][0];
}

for (var i = commonLength; i < arr2.length; i++) {
    obj2[arr2[i][1]] = arr2[i][0];
}

As the question is about efficiency, I made a jsperf test case to compare the solutions.

x-ray
  • 3,279
  • 5
  • 24
  • 37
-2
var obj1 = {},   

for (var i=0; i<arr1.length; i++) {

  obj1[arr1[i][1]] = arr1[i][0];

}  

for (var j=0; j<arr2.length; j++, i++) {

  obj2[arr2[i][1]] = arr2[j][0];

}

Hope this will you

Deep Kakkar
  • 5,831
  • 4
  • 39
  • 75
pooja
  • 1
  • 1