2

What would be an elegant way (jQuery or JavaScript) to merge such an array of objects:

var params = [
 {"name":"filter_color","value":"black"},
 {"name":"filter_color","value":"blue"},
 {"name":"filter_size","value":"l"},
 {"name":"filter_size","value":"m"}
];

into:

var params = [
 {"name":"filter_color","value":"black,blue"},
 {"name":"filter_size","value":"l,m"}
]

for later use in $.param(params)?

3
  • 1
    best in terms of what? Speed? Shortness of code? Either way it would be subjective depending on the person's experience. What have you tried? Commented Aug 17, 2017 at 13:03
  • 1
    This is not an associative array. This is an array of objects. Commented Aug 17, 2017 at 13:04
  • I can’t help it, but with almost every single “what is the best way to do X” question I come across here, it feels like that actually translates to “I have done f*ck all to research or solve this on my own, and now I expect you to list all possible ways, and also rank them for my by their ‘bestness’ (for which I of course did not even specify a single criterion) …” Commented Aug 17, 2017 at 13:08

2 Answers 2

2

You could use a hash table and group it by the wanted key.

function groupBy(array, key, fn) {
    var hash = Object.create(null);
    return array.reduce(function (r, o) {
        if (!hash[o[key]]) {
            hash[o[key]] = {};
            hash[o[key]][key] = o[key];
            r.push(hash[o[key]]);
        }
        fn(o, hash[o[key]]);
        return r;
    }, []);
}

var array = [{ name: "filter_color", value: "black" }, { name: "filter_color", value: "blue" }, { name: "filter_size", value: "l" }, { name: "filter_size", value: "m" }],
    result = groupBy(array, 'name', function (s, t) {
        t.value = t.value ? t.value + ',' + s.value : s.value;
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

1 Comment

This is exactly what I was looking for. Thanks a lot!
0

You can use Array.reduce method to convert your existing array into a new structure.

let arr = [
 {"name":"filter_color","value":"black"},
 {"name":"filter_color","value":"blue"},
 {"name":"filter_size","value":"l"},
 {"name":"filter_size","value":"m"}
];

let newArr = arr.reduce((acc, curr) => {
  if(acc.some(obj => obj.name === curr.name)) {
    acc.forEach(obj => {
      if(obj.name === curr.name) {
        obj.value = obj.value + " " + curr.value;
      }
    });
  } else {
    acc.push(curr);
  }
  return acc;
}, []);

console.log(newArr);

2 Comments

reduce + forEach? Oh god why..
You can change the forEach implementation. I just focused on reduce to display the new structure.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.