Search code examples
javascriptdry

DRY combine two functions in one


I am trying to refactor my code and have noticed I am repeating myself. Was wondering if there is a way to combine these two functions in one?

export const fn1 = article => article.categoryValueDtoSet.reduce((res, item) => {
  const result = { ...res };
  if (item.language) {
    const language = item.language.languageValue;
    const category = item.categoryValue;
    result[language] = category;
  }
  return result;
  }, { it: undefined, de: undefined, en: undefined );


  export const fn2 = article => article.titleDtoSet.reduce((res, item) => {
  const result = { ...res };
  if (item.language) {
    const language = item.language.languageValue;
    const category = item.titleValue;
    result[language] = title;
  }
  return result;
  }, { it: undefined, de: undefined, en: undefined );

Solution

  • First you would need function which you will pass to the reduce function as a callback. For this you can use a higher-order function which is basically a function that returns a function. We can call this function dry

    const dry = (fieldName) => (res, item) => {
      const result = { ...res };
      if (item.language) {
        const language = item.language.languageValue;
        result[language] = item[fieldName];
      }
      return result;
    }
    

    then we can extract the initial object that is being passed to the reduce callback:

    const intialValueObject = { it: undefined, de: undefined, en: undefined };
    

    and then pass the dry function to the reduce function as an argument:

    export const fn1 = article => article.categoryValueDtoSet.reduce(dry('categoryValue'), { ...initialValueObject });
    
    export const fn2 = article => article.titleDtoSet.reduce(dry('titleValue'), { ...intialValueObject });