HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Merge values of the objects properties with the same name into array

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
sametheobjectsmergepropertieswithintoarraynamevalues

Problem

I have such input:

[ { name: 'timezone', value: 'EST' },
  { name: 'interval', value: 'day' },
  { name: 'metrics[]', value: 1},
  { name: 'metrics[]', value: 2} ]


As you may already notice - these are parameters from POST request.

What I need to do is to get such output:

[ { name: 'timezone', value: 'EST' },
  { name: 'interval', value: 'day' },
  { name: 'metrics[]', value: [ 1, 2 ] },
  { name: 'metrics[]', value: [ 1, 2 ] } ]


My code does everything it needs to do, but I'm not sure if it is written in the optimal way, am I overlooking some bugs, etc.

arrayify = (params) ->
  arrayifiedParams = {}

  for param in params
    paramName = param.name

    arrayifiedParams[paramName] = arrayifiedParams[paramName] || []
    arrayifiedParams[paramName].push param.value        

  params.map (param) ->
    paramName = param.name
    if arrayifiedParams[paramName].length > 1
      param.value = arrayifiedParams[paramName]
    param


Here is the corresponding JSFiddle.

Solution

Your code looks ok overall. There are perhaps a few CoffeeScript features you can make use of, but nothing major.

However, I don't like that the input array is modified in-place (i.e. the function has side-effects). Other code may hold references to the param objects already, so altering them is potentially dangerous.

I'd rather have the function return a new, separate array with the results, leaving the input array untouched.

Here's a version that does that, and also removes duplicate params (I called it coalesce because it sounds fancier):

coalesce = (params) ->
  coalesced = {}

  for param in params
    {name, value} = param
    coalesced[name] or= []
    coalesced[name].push value

  for own name, value of coalesced
    value = value[0] if value.length is 1
    {name, value}

Code Snippets

coalesce = (params) ->
  coalesced = {}

  for param in params
    {name, value} = param
    coalesced[name] or= []
    coalesced[name].push value

  for own name, value of coalesced
    value = value[0] if value.length is 1
    {name, value}

Context

StackExchange Code Review Q#96258, answer score: 3

Revisions (0)

No revisions yet.