0

I need to create a javascript (jquery) array with duplicated key name like next one

{
    "apple": "type1",
    "apple": "type2",
}

Here is my current code I stack with

var data = {};
jQuery.each(formData, function(i, field) {
    data[field.name] = field.value;
});

In above example field.name is "apple" have different values like "type1" or "type2".

With my current code when same field.name in jQuery.each I got removed/erased "apple":"type1"

5
  • 5
    Object keys are unique, one key cannot store two values. Use an array, or an array of objects for this matter. Commented Jun 17, 2019 at 8:05
  • 5
    why not do it like { "apple" : ['type1' , 'type2'] } Commented Jun 17, 2019 at 8:07
  • It's an expected behavior since object keys are unique, If you want to have different values for the same key, you can use an array as a value Commented Jun 17, 2019 at 8:07
  • Possible duplicate of JS associative object with duplicate names Commented Jun 17, 2019 at 8:16
  • @Kevin.a because I have limitations by software, I can't rebuild it to use correct array structure. Commented Jun 17, 2019 at 9:17

1 Answer 1

1

This is not a jQuery problem, but rather it is to do with the nature of objects in javascript. You can't store multiple values on the same key (how would you access them?).

What you can do is store an array on a key, and add to that:

const formData = jQuery('input');
let data = {};

jQuery('button').click(function() {
  data = {}
  jQuery.each(formData, function(i, field) {
    data[field.name] = data.hasOwnProperty(field.name)
      ? [...data[field.name], field.value]
      : [field.value]
  });
  
  console.dir(data);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input name="a" />
<input name="b" />
<input name="b" />
<button>Test</button>

What the above code does is use an array against a key, and add to that array for each item.

You can do this without jQuery, and without an each, you may or may not prefer this option:

const button = document.querySelector('button');
const getAll = selector => Array.prototype.slice.call(
  document.querySelectorAll(selector)
);

let data = {};

button.onclick = () => {
  data = getAll('input')
    .reduce((result, element) => ({
      ...result,
      [element.name]: result.hasOwnProperty(element.name)
        ? [...result[element.name], element.value]
        : [element.value]
    }), {})
    
  console.dir(data)
}
<input name="a" />
<input name="b" />
<input name="b" />
<button>Test</button>

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

5 Comments

This breaks on multiple clicks, but I get the gist of it. Moving the object declaration inside the button click will fix this
@Kobe very true, good spot, thanks for that. Answer updated now
you are right but I was limited by software form which incorrectly allow to have inputs with same id/name but different values. Anyway your answer help me.
what three ... mean in the [...data[field.name]?
This is the spread syntax. It 'spreads' out the existing contents of that array into a new array.

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.