2

I ask you for your any help with the following problem. Thank you!

Assume that you are given a nested array with three slots. For example,

    var numbers = [1, [2,[3,4,5],[6,7,8]], [9,10,11]]

As you may notice, each array has three slots whether the slots are occupied by an integer or another array with three slots.

    [{"key1":1,"key2":"nothing","key3":[9,10,11]},{"key1":2,"key2":"nothing","key3":[6,7,8]},{"key1":9,"key2":"nothing","key3":11}]

My goal is roughly to list all the atomic arrays the given in the nested array and turn them into associative array. For example,

   [a,[b,c,d],e] -> [{key1: a, key2: X, key3: e}, {key1: b, key2: c, key3: d}]

If the element of an array is another array, the element might be given a name like "X".

    var arr = new Array();

    Array.prototype.node = function(){ 
       if (this.length == 1){
          arr.push({
             key1: this[0],
       })
       }
       else if (this.length == 2 ){
          arr.push({
             key1: this[0],
             key2: this[1],
          })
       }
       else if (this.length == 3){
          arr.push({
             key1: this[0],
             key2: "nothing",
             key3: this[2],
          })
       } 
    }

    Array.prototype.mkk = function (){
        switch(true){
           case(!this[0].isArray): {this.node()}
           case(this[1].length > 1): {this[1].node()}
           case(this[2].length > 1): {this[2].node()}
        }
    return arr
    }

    function myFunction() {
       var numbers = [1, [2,[3,[4,5,[]]], [4,[]]], [5,[]]]
      //do something like ... JSON.stringify(numbers.mkk())
    }
Michael43
  • 51
  • 3
  • Perhaps the `typeof` keyword will be of use to you: `typeof [...] // returns 'object'` [Mozilla typeof documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) – Patrick Barr Mar 28 '17 at 16:56
  • What is the purpose of `"nothing"` in your code? Also, I don't understand how this data structure is better for you: you are changing the property names `1` to `key1`, `2` to `key2` and lose the extra functions available for arrays. I don't get it. I would have understood if you wanted the transformation in the opposite direction, since you then gain functionality. – trincot Mar 28 '17 at 17:16
  • Just a quick link on [the dangers of extending native objects like `Array`](http://stackoverflow.com/q/14034180/2902660) – Pineda Mar 28 '17 at 17:21

2 Answers2

0

You could use this ES6 function:

function transform(arr) {
    return !Array.isArray(arr) ? arr 
        : Object.assign(...Object.keys(arr).map ( (key, i) =>
                ({ ['key' + (i+1)]: transform(arr[key]) })
            ));
}
// Sample call
const numbers = [1, [2,[3,4,5],[6,7,8]], [9,10,11]];
console.log(transform(numbers));
.as-console-wrapper { max-height: 100% !important; top: 0; }

I would not extend the Array object prototype for this. It is a too specific function, and really not very useful in general:

Arrays are objects of which the properties are sequential numbers. What you want here is to rename those numerical properties to key followed by that number, whereby you give up on the Array functionality you had first. Think of the forEach method, the length property, the sort method, ...etc. You give all this up, just to have property names which have key word in them. This does not really seem that useful.

trincot
  • 317,000
  • 35
  • 244
  • 286
0

You might do as follows;

function flatIntoObjects(a){
  return a.reduce((p,e,i) => Array.isArray(e) ? (p[0] = Object.assign(p[0], {["key"+ ++i]: "X"}), p.concat(flatIntoObjects(e)))
                                              : (p[0] = Object.assign(p[0], {["key"+ ++i]: e}), p), [{}]);
}
var numbers = [1, [2,[3,4,5],[6,7,8]], [9,10,11]];

console.log(flatIntoObjects(numbers));
Redu
  • 25,060
  • 6
  • 56
  • 76