mchl18
mchl18

Reputation: 2336

reduce key value pairs in JS Array to object

I have one object that I had to take apart into two arrays to handle properly. It looked like this:

{
  city:"stuttgart",
  street:"randomstreet",
  ...
}

Since it needs to fit a certain directive I had to convert it to:

[
  {key:"city", value:"stuttgart"}
  {key:"street", value:"randomstreet"},
  ...
]

for this I first used

var mapFromObjectWithIndex = function (array) {
  return $.map(array, function(value, index) {
    return [value];
  });
};

var mapFromObjectWithValue = function (array) {
  return $.map(array, function(value, index) {
    return [index];
  });
});

to create two arrays, one containing the old key, the other one is holding the old value. Then I created another, two dimensional array map them into a single array doing this

var mapToArray = function (arrayValue, arrayIndex) {
  var tableData = [];
  for (var i = 0; i<arrayIndex.length; i++){
    tableData[i] = {key:arrayIndex[i] , value:arrayValue[i]};
  }
  return tableData;
};

(maybe I have already messed up by here, can this be done any easier?)

Now, I use the array (tableData) to display the data in a form. The value fields can be edited. In the end, I want to convert the array (tableData) to its original. (see first object)

Please note, that the original object doesn't only contain strings as values, but can also contain objects as well.

Upvotes: 2

Views: 10574

Answers (4)

rpadovani
rpadovani

Reputation: 7360

I think conversion can be definitely easier:

var obj = {
  city:"stuttgart",
  street:"randomstreet",
};

var tableData = Object.keys(obj).map(k => {return {key: k, value: obj[k]}});

console.log(tableData);

var dataBack = {};
tableData.forEach(o => dataBack[o.key] = o.value);

console.log(dataBack);

What do you want to do with objects? Do you want to expand them as well? If yes you can do something like this (and it works with nested objects as well):

var obj = {
  city:"stuttgart",
  street:"randomstreet",
  obj: {a: 'a', b: 'b'},
  subObject: {aha: {z: 'z', y: 'y'}}
};

function trasformToTableData(obj) {
  if (typeof obj !== 'object') return obj;
  return Object.keys(obj).map(k => {return {key: k, value: trasformToTableData(obj[k])}});
}

var tableData = trasformToTableData(obj);
console.log(tableData);

function transformBack(obj) {
  if (Array.isArray(obj)) {
    var support ={};
    for (let i = 0; i < obj.length; i++) {
      support[obj[i].key] = transformBack(obj[i].value)
    }
    return support;
  }
  return obj;
}

var dataBack = {};
tableData.forEach(o => dataBack[o.key] = transformBack(o.value));

console.log(dataBack);

Upvotes: 12

Redu
Redu

Reputation: 26161

Let's have some fun and turn our object into iterable to do the job as follows;

var input = {city:"stuttgart", street:"randomstreet", number: "42"};
   output = [];
input[Symbol.iterator] = function*(){
                           var ok = Object.keys(this),
                                i = 0;
                           while (i < ok.length) yield {key : ok[i], value: this[ok[i++]]};
                         };
output = [...input];
console.log(output);

Upvotes: 3

Corey Sery
Corey Sery

Reputation: 121

I would do something like this:

var dataObj = {
  city:"stuttgart",
  street:"randomstreet",
};

function toKeyValue(obj) {
  var arr = [];
  for (var key in obj) {
    if(obj.hasOwnProperty(key)) {
      arr.push({'key': key, 'value': obj[key]});
    }
  }
  return arr;
}

var arrayKeyValue = toKeyValue(dataObj);
console.log(arrayKeyValue);

Upvotes: 1

Joah Gerstenberg
Joah Gerstenberg

Reputation: 441

This function will map your object to an array when you call objVar.mapToArray(), by using Object.keys() and .map()

Object.prototype.mapToArray = function() {
  return Object.keys(this).map(function(v) {
    return { key: v, value: this[v] };
  }.bind(this));
}

Upvotes: 2

Related Questions