【问题标题】:JavaScript function composition from 3 functions由 3 个函数组成的 JavaScript 函数
【发布时间】:2017-05-26 04:41:59
【问题描述】:

我正在使用 Vue 并尝试使用 JS 函数组合过滤结果数组。

我的 Vue 计算值是这样的,但无法让 filteredByAll 接受第三个选项 getByThing。现在 filterByAll 只过滤类别和关键字搜索。

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)
      }
    }

我的标准 JS 函数

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)
}

我正试图将我的头脑围绕在功能性的东西上,但从我所阅读的内容中挣扎。

【问题讨论】:

    标签: javascript arrays function functional-programming


    【解决方案1】:

    当我们将函数重写为curried 版本并且最后一个参数是我们可以compose 他们喜欢的列表时:

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

    工作代码

    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))

    【讨论】:

      【解决方案2】:

      应该这样做:

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

      【讨论】:

      • 啊,因为从最里面到最外面,对吧?
      • 是的,每个函数都返回一个列表,因此您可以简单地将一个函数的结果作为列表参数插入下一个函数。该顺序仅在人们可以通过首先过滤产生最少结果数量的任何事物来优化速度的情况下才有意义。
      • 谢谢克里斯 - 我认为我明白了,我以前哪里出错了。我想我正在尝试另一种方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 2012-09-19
      • 2011-11-03
      • 2015-08-02
      • 1970-01-01
      相关资源
      最近更新 更多