Alex Lemesios
Alex Lemesios

Reputation: 532

Javascript functional programming / Passing parameters

I started experimenting with functional programming lately and I'm trying to convert an old module I have written using imperative programming.

Let's say I have two arrays of objects i.e

orders: [
  {
   idOrder: 1,
   amount: 100,
   customerId: 25,
  },
  {
   idOrder: 2,
   amount: 200,
   customerId: 20,
  }
]


customers: [
  {
   customerId: 20,
   name: "John Doe",
   orders: []
  },
  {
   customerId: 25,
   name: "Mary Jane",
   orders: []
  }
]

I want to push all the orders to their respective customer. Is there a clean way of doing it?

I have tried this , but obviously it doesn't work that way :

customers.orders = orders.filter((x) => {
  if (x.customerId === customerId) {
    customer.orders.push(x);
  }
});

Thanks

Upvotes: 0

Views: 131

Answers (4)

cnexans
cnexans

Reputation: 994

You can write a function and pass it to reduce method and compose it with map

Just one things: once it's created, it may never change. You can user Object.assign and concat.

var customersWithOrders = customers.map(function(customer) {
  var relatedOrders = orders.filter(function(order) { return order.customerId === customer.customerId })
  return Object.assign(
    customer, 
    {
      orders: customer.orders.concat(relatedOrders)
    }
  )
})

Upvotes: 0

Scott
Scott

Reputation: 1688

If you think of customers as your accumulator you can Reduce orders with customers as your initial value.

NOTE: this does mutate customers if you do not want this as a side-effect you would have to clone customers. Also there is not error handling for customerId not found.

var orders =  [{ idOrder: 1, amount: 100, customerId: 25 }, { idOrder: 2, amount: 200, customerId: 20}];
var customers =  [{ customerId: 20, name: "John Doe", orders: [] }, { customerId: 25, name: "Mary Jane", orders: [] } ];

var customers_orders = orders.reduce( 
               (accum, v) => 
                   { accum.find(
                            c => c.customerId == v.customerId).orders.push(v);
                     return accum; 
                   }, customers);

console.log(customers_orders);

Upvotes: 0

Julian
Julian

Reputation: 111

Possible solution:

for (c of customers){
    c.orders.push(orders.filter( function(o){ return o.customerId === c.customerId} ));

}

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386848

You could use a Map and get all customers first and then push the orders to the customers.

var object = { orders: [{ idOrder: 1, amount: 100, customerId: 25 }, { idOrder: 2, amount: 200, customerId: 20 }], customers: [{ customerId: 20, name: "John Doe", orders: [] }, { customerId: 25, name: "Mary Jane", orders: [] }] },
    map = object.customers.reduce((m, a) => m.set(a.customerId, a), new Map);

object.orders.forEach(a => map.get(a.customerId).orders.push(a));

console.log(object.customers);

Upvotes: 2

Related Questions