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)?

unostar
  • 43
  • 1
  • 7
  • 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? – Script47 Aug 17 '17 at 13:03
  • 1
    This is not an associative array. This is an array of objects. – Eren Tantekin Aug 17 '17 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) …”_ – CBroe Aug 17 '17 at 13:08

2 Answers2

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; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
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);
Anurag Singh Bisht
  • 2,683
  • 4
  • 20
  • 26