Get array of objects from query params object

704 Views Asked by At

I have object with queryparams keys and values such as:

 const params = {
      'filter[0][key]': 'name',
      'filter[0][operator]': 'like',
      'filter[0][value]': 'test',
      
      'filter[1][key]': 'age',
      'filter[1][operator]': '=',
      'filter[1][value]': '21'
    }

I need to get from this an array of objects like this:

const filter = [
  {
    key: 'name',
    operator: 'like',
    value: 'test'
  },
  {
    key: 'age',
    operator: '=',
    value: '21'
  }
]
3

There are 3 best solutions below

2
On BEST ANSWER

This should work if there's only 3 levels.

const params = {
  'filter[0][key]': 'name',
  'filter[0][operator]': 'like',
  'filter[0][value]': 'test',
  'filter[1][key]': 'age',
  'filter[1][operator]': '=',
  'filter[1][value]': '21'
}

const result = {};
for (const key in params) {
  const [[,...splits]] = [...key.matchAll(/(\w+)\[(\w+)]\[(\w+)]/g)]; // Using destructuring, to pick out the matched groups of the key.
  
  result[splits[0]] ??= isNaN(+splits[1]) ? {} : []; // If the next key is a number, then this object should be an array if not it should be an object
  result[splits[0]][splits[1]] ??= isNaN(+splits[2]) ? {} : [];
  result[splits[0]][splits[1]][splits[2]] = params[key];
}

console.log(result.filter);

0
On

This will work too.

 const params = {
      'filter[0][key]': 'name',
      'filter[0][operator]': 'like',
      'filter[0][value]': 'test',
      
      'filter[1][key]': 'age',
      'filter[1][operator]': '=',
      'filter[1][value]': '21'
    }
const keys = Object.keys(params)
var res = keys.reduce(function (r, a) {
    r[a[7]] = r[a[7]] || [];
    temp = a.slice(10,-1);
    r[a[7]].push({[temp]:params[a]});
    return r;
    }, Object.create(null));
    
const filter=[]    
for (var k in res) {
    filter.push(Object.assign({}, ...res[k]))
}   
console.log(filter)

0
On

Declarative way, should work for any amount of keys and items (won't work for nested objects):

 const params = {
      'filter[0][key]': 'name',
      'filter[0][operator]': 'like',
      'filter[0][value]': 'test',
      'filter[1][key]': 'age',
      'filter[1][operator]': '=',
      'filter[1][value]': '21',
      'filter[2][key]': 'A',
      'filter[2][operator]': 'B',
      'filter[2][value]': 'C'
    }
    
const items = Object.entries(params)
const allKeys = items.map(e => e[0].replace(/(.*)\[(.*)\]/, '$2'))
const uniqueKeys = [...new Set(allKeys)]
const resLen = items.length / uniqueKeys.length
const res = Array.from({length: resLen}, (_, i) => 
               uniqueKeys.reduce((acc, e, j) => {
                  acc[e] = items[resLen * i + j][1]
                  return acc
               }, {}))
console.log(res)