0

I have an array like this:

var arr = [
    ['a1','b1','c1','d1'],
    ['a1','e1','i1','j1'],
    ['a1','f1','k1','l1'],
    ['a1','g1','m1','n1'],
    ['a1','h1','o1','p1'],
    ['a2','b2','c2','d2'],
    ['a2','e2','i2','j2'],
    ['a2','f2','k2','l2'],
    ['a2','g2','m2','n2'],
    ['a2','h2','o2','p2']
];

and I want to convert it to an object like this:

var converted_arr = {
    'a1':{
        'b1':['c1','d1'],
        'e1':['i1','j1'],
        'f1':['k1','l1'],
        'g1':['m1','n1'],
        'h1':['o1','p1'],
    },
    'a2':{
        'b2':['c2','d2'],
        'e2':['i2','j2'],
        'f2':['k2','l2'],
        'g2':['m2','n2'],
        'h2':['o2','p2'],
    }
};

As you can see all the items of the first array (arr) are arrays and it's item in these arrays are strings or numbers or both.
One of the examples I have tried is the following:

var obj = {};
$.each(arr,function(a)
{
    obj[a[0]][a[1]] = a.slice(2);
});

But it produces nothing.
Can someone help me out?

3
  • Please post the code which you have tried. And where exactly you are stuck? Commented Mar 3, 2019 at 12:32
  • Answered below. Please consider variable naming carefully. converted_arr is a poor choice because arr suggests that the value is an array when actually it is an object. converted would be a poor choice because it's essentially meaningless. Choose a name that's indicative of the purpose/meaning of the value for your final solution. Good luck! Commented Mar 3, 2019 at 12:50
  • @Sunil Example given! Hope you can help me out with it! Commented Mar 3, 2019 at 16:26

4 Answers 4

3

You could use reduce and destructuring like this:

var arr = [
    ['a1','b1','c1','d1'],
    ['a1','e1','i1','j1'],
    ['a1','f1','k1','l1'],
    ['a1','g1','m1','n1'],
    ['a1','h1','o1','p1'],
    ['a2','b2','c2','d2'],
    ['a2','e2','i2','j2'],
    ['a2','f2','k2','l2'],
    ['a2','g2','m2','n2'],
    ['a2','h2','o2','p2']
];

const newArray = arr.reduce((acc, [key, key2, ...rest]) => {
  acc[key] = acc[key] || {};
  acc[key][key2] = rest
  return acc;
}, {})

console.log(newArray)

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

Comments

0

You are on right track. Just the function usage was wrong. I have reused the code and updated it to make it work fine. For $.each function, the first value is the index (docs) which was the main cause for error.

I have update the code and it works fine.

var arr = [
    ['a1','b1','c1','d1'],
    ['a1','e1','i1','j1'],
    ['a1','f1','k1','l1'],
    ['a1','g1','m1','n1'],
    ['a1','h1','o1','p1'],
    ['a2','b2','c2','d2'],
    ['a2','e2','i2','j2'],
    ['a2','f2','k2','l2'],
    ['a2','g2','m2','n2'],
    ['a2','h2','o2','p2']
];
obj = {}
$.each(arr,function(index)
{
    obj[arr[index][0]] = obj[arr[index][0]] || {}
    obj[arr[index][0]][arr[index][1]] = arr[index].slice(2);
});
console.log(obj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Note: The solution is specific for above requirement. However, it can be generalized as well using recursion.

Hope it helps. Revert for any doubts/clarifications.

Comments

-1

Using reduce in the Lodash library you could do the following, where arr is your input array.

_.reduce(arr, function(acc, val) { var k1 = val[0], k2 = val[1], val = val.slice(2); acc[k1] = acc[k1] || {}; acc[k1][k2] = val; return acc; }, {});

2 Comments

You're suggesting a library the OP has not mentioned, plus, this is available now in most modern browsers natively, without a library.
Granted Darren, however the OP didn't say that he's targeting a modern browser, lodash is ubiquitous so he's probably using it already, and he will discover a useful library that will stand him in good stead if he isn't aware of it already. So I went for the safer and potentially more educational version. The expressiveness of the more recent JS is a joy to behold though!
-1

Here's a simple example working for a list of lists (as per your examples), with the min size of leaf arrays being passed as parameter (in your case set to 2).

The mapping extracts a key and accumulates arrays, while the normalizing reduces the arrays recursively, until a satisfying result has been reached.

var arr = [
    ['a1','b1','c1','d1'],
    ['a1','e1','i1','j1'],
    ['a1','f1','k1','l1'],
    ['a1','g1','m1','n1'],
    ['a1','h1','o1','p1'],
    ['a2','b2','c2','d2'],
    ['a2','e2','i2','j2'],
    ['a2','f2','k2','l2'],
    ['a2','g2','m2','n2'],
    ['a2','h2','o2','p2']
];

console.log(transform(arr, 2));

function transform(input, minSize) {

  return normalize(map(input, {}), minSize);

  function map(input, result) {
    for (var ii = 0; ii < input.length; ii++) {
      var row = input[ii];
      if (row.length == 0) {
        continue;
      }

      var first = row[0];
      var list = result[first] || (result[first] = []);
      list.push(cdr(row));
    }
    return result;
  }

  function normalize(result, minSize) {
    for (var key in result) {
      var list = result[key];
      if (list.length == 0) {
        continue;
      }
      var first = list[0];
      if (list.length == 1 && first.length <= minSize) {
        result[key] = first;
        continue;
      }
      result[key] = transform(list, minSize);
    }
    return result;
  }

  function cdr(list) {
    var result = [];
    for (var ii = 1; ii < list.length; ii++) {
      result.push(list[ii]);
    }
    return result;
  }
}

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.