AlexioVay
AlexioVay

Reputation: 4527

Save data values from an input into an multidimensional array

var dataArray = [];
dataArray.push({ items: [] });
var items = $('#services_hidden').val();
var itemsArray = items.split(",");
console.log("itemsArray: " + itemsArray);
$.each( itemsArray, function( index, value ){
    dataArray[0].items.push(value);
});
console.log("dataArray " + JSON.stringify(dataArray));

This way I want to save data in an array reading an input value that like this:

<input id="services_hidden" value="item1,value1,item2,value2,item3,value3" />

So there can be multiple items assigned to a specific value. At the moment it looks like this which is wrong because it's all saved into items not seperated from each other:

dataArray [{"items":["item1","value1","item2,"value2"]}]

But I want this (I hope I show this correctly):

dataArray [{"items":{"item1:value1"},{"item2:value2"}}]

So the parent is items and every two values in #services_hidden.val() seperated by a comma should create an key:value pair.

What do I have to change in my code to achieve this?

Upvotes: 1

Views: 69

Answers (4)

Nenad Vracar
Nenad Vracar

Reputation: 122047

You can use reduce() do do this

//Select element by id and get value
var val = document.getElementById('services_hidden').value;
//Split value at , and create array
var ar = val.split(',');

//Use reduce to return result in data_array variable
var data_array = ar.reduce(function(r, e, i) {
  //If index of element is odd number, add to result, element of array with previous index number and then current element
  if (i % 2) r[0].items = (r[0].items || []).concat({
    [ar[i - 1]]: e
  });
  //return result array.
  return r;
}, [{}]);

//Add result to HTML
document.body.innerHTML += '<pre>' + JSON.stringify(data_array) + '</pre>';
<input id="services_hidden" value="item1,value1,item2,value2,item3,value3" />

Upvotes: 1

akinuri
akinuri

Reputation: 12027

Let's stick to your original format and be as simple as it can be:

var dataArray = [];
dataArray.push({ items: [] });

var items = "item1,value1,item2,value2,item3,value3"; // $('#services_hidden').val()
var itemsArray = items.split(",");

for (var i = 0; i < itemsArray.length; i+=2) {
  var item = itemsArray[i];
  var value = itemsArray[i+1];
  var itemObj = {};
  itemObj[item] = value;
  dataArray[0].items.push(itemObj);
}

console.log("dataArray " + JSON.stringify(dataArray));

The only thing that might need an explanation is for (var i = 0; i < itemsArray.length; i+=2) {. Why increase i by 2? You have 6 items in itemsArray and we'll be inserting 3 items to the dataArray[0].items. We don't need to iterate 6 times.

["item1", "value1", "item2", "value2", "item3", "value3"]
    i       (i+1)      i       (i+1)      i       (i+1)

Since the itemns and valuens are next to each other, we can use i to access the item, and i+1 to access the value.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386624

I suggest to use Array#forEach, because it visits each element and process it.

var val = document.getElementById('services_hidden').value,
    data_array = [{ items: [] }];
 
data_array[0].items ;
val.split(',').forEach(function(a, i) {
    var o = {};
    if (i & 1) {
        o[this.key] = a;
        data_array[0].items.push(o)
        return;
    }
    this.key = a;
}, { key: null });

document.body.innerHTML += '<pre>' + JSON.stringify(data_array) + '</pre>';
<input id="services_hidden" value="item1,value1,item2,value2,item3,value3" />

Upvotes: 1

rvighne
rvighne

Reputation: 21897

Loop over the split array, except increment by twos. That way, each iteration, itemsArray[i] is the key and itemsArray[i + 1] is the value.

for (let i = 0; i < itemsArray.length; i += 2) {
    let key = itemsArray[i];
    let value = itemsArray[i + 1];
    dataArray[0].items.push(key + ':' + value);
}

Replace let with var above if you want to support older browsers. Here's a demo (the result will update live as you change the <input>):

var input = document.getElementById('services_hidden');
var pre = document.getElementById('result');

function update() {
  var itemsArray = input.value.split(',');

  var dataArray = [
    {
      items: []
    }
  ];

  for (var i = 0; i < itemsArray.length; i += 2) {
    var key = itemsArray[i];
    var value = itemsArray[i + 1];
    dataArray[0].items.push(key + ':' + value);
  }

  pre.textContent = JSON.stringify(dataArray, null, 4);
}

input.addEventListener('input', update);
update();
<input id="services_hidden" value="item1,value1,item2,value2,item3,value3" />

<pre id="result"></pre>

Upvotes: 1

Related Questions