user278639 user278639 - 14 days ago 4
CoffeeScript Question

What is a succinct way to write a coffeescript function that converts my json array into the format that I want

I have this json object:

op = [{"id":7,"d_set_id":1,"option_value_id":5,"product_id":3,"model":"1300","option_type":"Plunger Diameter","option":"5.0 inch Plunger Diameter","product":"Packing","route":"part_option_values","reqParams":null,"restangularized":true,"fromServer":true,"parentResource":{"route":"parts","parentResource":null,"id":"29"},"restangularCollection":false},{"id":9,"d_set_id":5,"option_value_id":11,"product_id":3,"model":"1300","option_type":"main drum diameter","option":"1.0 main drum diameter","product":"Packing","route":"part_option_values","reqParams":null,"restangularized":true,"fromServer":true,"parentResource":{"route":"parts","parentResource":null,"id":"29"},"restangularCollection":false}]

I wrote this function to convert it to the format that I want:

addItems: (op) ->
variant = {
product_id: "undefined"
model: "undefined"
options: []
product: "undefinded"
option_value_ids: []
quantity: 1
op.forEach (obj,i) ->
variant.product_id = obj.product_id
variant.model = obj.model
variant.options.push obj.option
variant.product = obj.product
variant.option_value_ids.push obj.option_value_id
variant.options = variant.options.join(', ')
items.push variant

It successfully changes it into my desired result.

items = [{"product_id":3,"model":"1300","options":"5.0 inch Plunger Diameter, 1.0 main drum diameter","product":"Packing","option_value_ids":[5,11],"quantity":1},{"product_id":3,"model":"1300","options":"5.0 inch Plunger Diameter, 1.0 main drum diameter","product":"Packing","option_value_ids":[5,11],"quantity":1}]

... but this doesn't seem like a very succinct way to write this function. What is a better way?


Yes! This can all be done succinctly with three concepts. Maps, destructuring and Object Shorthand notation (all three available in ES2015/6 as well as coffeescript)

options = []
ids = []

# We need to aggregate id's and options first
for {option_value_id, option} in op
  ids.push option_value_id
  options.push option

# Map through to the new Object
items = ({ product_id, model, product}) ->
    options: options
    option_value_ids: ids
    quantity: 1
  } will take an array and transform each element (in this case a subset of the bigger object) and return a new Array. We will destructure the incoming object in the arguments and then shorthand them back into an object format.

Array Map

Object Destructuring

Shorthand Notation