简体   繁体   中英

JavaScript function composition from 3 functions

I'm using Vue and trying to filter an array of results using a JS function composition.

My Vue computed values are like so, but can't get filteredByAll to accept a third option getByThing . Right now the filterByAll just filters on the category and keyword search.

computed: {
        filteredByAll() {
        return getByCategory(getByKeyword(this.list, this.keyword), this.category)
      },
      filteredByKeyword() {
          return getByKeyword(this.list, this.keyword)
      },
      filteredByCategory() {
          return getByCategory(this.list, this.category)
      },
      filteredByThing() {
        return getByThing(this.list, this.thing)
      }
    }

My standard JS functions

function getByKeyword(list, keyword) {
  const search = keyword.trim()
  if (!search.length) return list
  return list.filter(item => item.name.indexOf(search) > -1)
}

function getByCategory(list, category) {
  if (!category) return list
  return list.filter(item => item.category === category)
}

function getByThing(list, thing) {
  if (!thing) return list
  return list.filter(item => item.thing === thing)
}

I'm trying to wrap my head around the functional stuff but struggling from what I've read.

This should do it:

filteredByAll() {
    return getByThing(getByCategory(getByKeyword(this.list, this.keyword), this.category), this.thing)
},

When we rewrite the functions to a curried version and the last argument is the list we can compose them like:

const trippleFilter = (keyword, category, thing) => pipe (
    getByKeyword (keyword),
    getByCategory (category),
    getByThing (thing)
)

Working Code

 const pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))) const getByKeyword = keyword => list => { const search = keyword.trim() return !search.length ? list : list.filter(item => item.name.indexOf(search) > -1) } const getByCategory = category => list => !category ? list : list.filter(item => item.category === category) const getByThing = thing => list => !thing ? list : list.filter(item => item.thing === thing) const trippleFilter = (keyword, category, thing) => pipe ( getByKeyword (keyword), getByCategory (category), getByThing (thing) ) const x = [ { name: 'pizza', category: 'fastfood', thing: 'pizza salami' }, { name: 'burger', category: 'fastfood', thing: 'hamburger' } ] console.log(trippleFilter ('pizza', 'fastfood', 'pizza salami') (x)) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM