Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write a pure function to return one object from inner properties another objects?

Doing some data transformation exercises and getting stuck. I have an object that I want to transform to look likefrom (starting) -> to (expected ending) output described below. I'm trying to use Array.reduce and Object.assign to keep the output pure. but I just cannot get it to work properly.

/**
 *  from (starting): {topic: {id: 2}, products: {id: 3}}
 *  to (expected ending):   {topic: 2, products: 3}
 */

const starting = {topic: {id: 2}, products: {id: 3}};

const ending = Object.keys(starting).reduce((p, key) => {
  if(!p[key]) p[key] = key;
  return Object.assign(p[key], starting[key].id);  
}, {})
like image 599
Armeen Harwood Avatar asked Jan 30 '18 21:01

Armeen Harwood


People also ask

What is pure function with example?

A function is called pure function if it always returns the same result for same argument values and it has no side effects like modifying an argument (or global variable) or outputting something. The only result of calling a pure function is the return value. Examples of pure functions are strlen(), pow(), sqrt() etc.

What is the pure function in Javascript?

A Pure Function is a function (a block of code) that always returns the same result if the same arguments are passed. It does not depend on any state or data change during a program's execution. Rather, it only depends on its input arguments.

What is a pure function in programming?

A pure function is a function which: Given the same input, will always return the same output. Produces no side effects.

Can pure functions make API calls?

No to both, as they return different values for the same input. But that applies same for fetch, it might return different values on each call (data update, server is down, network error, etc.) Calling pureHttpCall by itself does not make a http request. It only returns a function.


4 Answers

You can use reduce, just remember to return the starting object after each iteration.

function convert(start) {
  return Object.keys(starting).reduce((o, key) => {
      o[key] = start[key].id;
      return o;
    }, {});
}

const starting = {topic: {id: 2}, products: {id: 3}};
console.log(convert(starting));
like image 64
KevBot Avatar answered Oct 21 '22 18:10

KevBot


Try this:

var starting = {topic: {id: 2}, products: {id: 3}};

var ending = Object.keys(starting).reduce((p, key) => {
  p[key] = starting[key].id;
  return p;
}, {})

This will create a new object, so no need for Object.assign and such to keep the output pure.

like image 33
Jorge Fuentes González Avatar answered Oct 21 '22 18:10

Jorge Fuentes González


I don't think reduce() is the right tool for this.

Try iterating through starting's keys using forEach() instead:

const starting = {topic: {id: 2}, products: {id: 3}};

const ending = {};
Object.keys(starting).forEach(p => ending[p] = starting[p].id);

console.log(ending);
like image 33
Rick Hitchcock Avatar answered Oct 21 '22 19:10

Rick Hitchcock


A pure function solution would require you to return a new object on each iteration:

function convert(start) {
  return Object.keys(starting).reduce((o, key) => 
    Object.assign({}, {
      [key]: start[key].id
    }, o), {});
}

const starting = {topic: {id: 2}, products: {id: 3}};

console.log(convert(starting));

Using object spread makes it a bit cleaner:

function convert(start) {
  return Object.keys(starting).reduce((o, key) => ({
    ...o,
    [key]: start[key].id
  }), {});
}

const starting = {topic: {id: 2}, products: {id: 3}};

console.log(convert(starting));
like image 23
nem035 Avatar answered Oct 21 '22 18:10

nem035