DEV Community

KarmaBlackshaw
KarmaBlackshaw

Posted on • Updated on

Have you tried piping in Javascript?

Have you ever caught yourself doing something like this?

Problem: To get the class where all students' name contains the letter 'J':

const studentsByClass = {
  class_1: ['john', 'mark', 'josh'],
  class_2: ['jeash', 'jack', 'jean']
}

const result = Object.fromEntries(Object.entries(studentsByClass)
  .filter(([className, students]) => {
    return students.every(studentName => studentName.includes('j'))
  }))
Enter fullscreen mode Exit fullscreen mode

It's pretty long right? Pretty hard to read as well.

Recently, I've found a way to make this readable. I've found this article from freecodecamp.org about pipe function.

It goes like this:

const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

const toEntries = val => Object.entries(val)

const filterClass = entries => {
  return entries.filter(([className, students]) => {
    return students.every(studentName => studentName.includes('j'))
  })
}

const fromEntries = entries => Object.fromEntries(val)

pipe(
  toEntries,
  filterClass,
  fromEntries,
)(studentsByClass);
Enter fullscreen mode Exit fullscreen mode

This has really helped me with the long lines of code. But I am not yet comfortable with the functional javascript. So I made my own version:

const pipe = (initial, fns) => fns.reduce((v, f) => f(v), initial)
Enter fullscreen mode Exit fullscreen mode

How to use it:

const pipe = (initial, fns) => fns.reduce((v, f) => f(v), initial)

const toEntries = val => Object.entries(val)

const filterClass = entries => {
  return entries.filter(([className, students]) => {
    return students.every(studentName => studentName.includes('j'))
  })
}

const fromEntries = entries => Object.fromEntries(val)

pipe(studentsByClass, [
  toEntries,
  filterClass,
  fromEntries,
]);
Enter fullscreen mode Exit fullscreen mode

But, I usually do it like this to avoid cluttered codebase.

const pipe = (initial, fns) => fns.reduce((v, f) => f(v), initial)

const filterClass = entries => {
  return entries.filter(([className, students]) => {
    return students.every(studentName => studentName.includes('j'))
  })
}

pipe(studentsByClass, [
  val => Object.entries(val),
  val => filterClass(val),
  val => Object.fromEntries(val)
]);
Enter fullscreen mode Exit fullscreen mode

Sources/Reads
freecodecamp
github

Top comments (0)