0

I have a compose function what should be called with n number of function, depending by what function was added as parameter. For example:

const props = ['link', 'letter'];

const mapp = {
  letter: (v) => {
    v + 'letter'
  },
  link: (v) => {
    v + 'nr'
  }
}

const compose = (...fns) =>
  fns.reduce(
    (prevFn, nextFn) =>
    (...args) =>
    nextFn(prevFn(...args)),
    (value) => value,
  );


const res = compose(props);

console.log(res('test'))

So, i expect, if the const props = ['link', 'letter']; the compose function should be called like: const res = compose(mapp[letter], mapp[link]);, or if const props = ['letter'];, the compose function should be called as: compose(mapp[letter]). At the moment the code does not work as expeted.
Question: How to fix the code and to get the expected result?

1
  • what is your expected result and BTW both letter and link property of mapp that are functions are returning nothing. Is this correct? I mean what is it for? Commented Sep 1, 2021 at 12:11

2 Answers 2

2

There was 2 problems with your code

  1. Missing return statement(s) in the mapp object's functions (or remove the { and } - see below)
  2. You needed to map the string array into references to the functions and spread (...) the result when calling compose

Working example:

const props = ['link', 'letter'];

const mapp = {
  letter: (v) => {
    return v + 'letter'
  },
  link: (v) => {
    return v + 'nr'
  }
}

const compose = (...fns) =>
  fns.reduce(
    (prevFn, nextFn) => (...args) => nextFn(prevFn(...args)),
    (value) => value,
  );


const res = compose(...props.map(p => mapp[p]));
console.log(res('test'))

Regarding 1. above that object could be written as below:

const mapp = {
  letter: (v) => v + 'letter',
  link: (v) => v + 'nr'
}

Edit: The need to destructure the call to map is because of the way you defined compose to take discrete parameters rather than an array. ie, this would also work (and not need to destructure map)

const props = ['link', 'letter'];

const mapp = {
  letter: (v) => {
    return v + 'letter'
  },
  link: (v) => {
    return v + 'nr'
  }
}

const compose = (fns) => /// compose now takes an array of functions
  fns.reduce(
    (prevFn, nextFn) => (...args) => nextFn(prevFn(...args)),
    (value) => value,
  );


const res = compose(props.map(p => mapp[p]));
console.log(res('test'))

Sign up to request clarification or add additional context in comments.

4 Comments

why ...props.map(p => mapp[p]), but not props.map(p => mapp[p]) ? why do we need to destructure ?
@Asking because as you said in your question you need it to be like const res = compose(mapp[letter], mapp[link]); - if you dont destructure its more like const res = compose([mapp[letter], mapp[link]]); which will wok, you just need to change your compose method to compose(fns){} not compose(...fns){}
got you. Thanks
@Asking Updated answer with some detail.
1

I do not see how you are using the object with the functions and you are not returning correctly in a few places. It should look something like

const props = ['link', 'letter'];

const mapp = {
  letter: (v) => v + 'letter',
  link: (v) => v + 'nr',
}

const compose = (obj, fns) => (...orgArgs) => 
  fns.reduce((args, fnName) => obj[fnName].apply(obj, [args]), orgArgs);

const res = compose(mapp, props);

console.log(res('test'))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.