【问题标题】:The correct approach to create multi-argument functions创建多参数函数的正确方法
【发布时间】:2020-12-17 11:16:51
【问题描述】:

我想到了在 JavaScript 函数式编程和 Ramda 中创建函数的正确方法。

我们有deviceTypesdevices 的集合和filter 的对象:

const deviceTypes = {
    phone: 'phone',
    tv: 'tv',
    watch: 'watch',
}

const devices = [
    {
        title: "My awesome watch",
        type: deviceTypes.watch,
    },
    {
        title: "My awesome phone",
        type: deviceTypes.phone,
    }
]

const filter = {
    deviceType: [deviceTypes.watch]
}

现在,我想显示由deviceType 过滤的设备并在标题中添加一些文本。

我创建了一个函数:

const extendTitle = ({item, ...rest}) => ({ title: `${item.title} - Hello world`, ...rest })
const filter = filter(({type}) => filter.deviceType.includes(type))

const filterAndExtendTitle = pipe(
    filter,
    extendTitle
)

filterAndExtendTitle(devices)

现在,我有一个问题。如果我想用deviceTypes(纯函数)添加第二个参数,我应该如何编写函数?

我正在尝试...

const extendTitle = ({item, ...rest}) => ({ title: `${item.title} - Hello world`, ...rest })
const filterItemsByType = (filter) => filter(({type}) => filter.includes(type))

const filterAndExtendTitle = (filter) = pipe(
    filterItemsByType(filter),
    extendTitle
)

filterAndExtendTitle(devices)(filter.deviceType) 

... 并且工作正常,但我不知道这种做法是否适合最佳做法。我考虑过curry 函数并对其进行修改以进行重构。

【问题讨论】:

    标签: javascript functional-programming ramda.js


    【解决方案1】:

    使用 Ramda 和 curried 函数,您可以创建一些可以重用的辅助函数

    (例如下面的 deviceTypeFilter)

    const { filter, assoc, curry, propSatisfies, map, pipe, contains } = R;
    
    const deviceTypes = {
      phone: 'phone',
      tv: 'tv',
      watch: 'watch'
    };
    
    const deviceList = [
      {
        title: "My awesome watch",
        type: deviceTypes.watch,
      },
      {
        title: "My awesome tv",
        type: deviceTypes.tv,
      },
      {
        title: "My awesome phone",
        type: deviceTypes.phone,
      }
    ];
    
    const itemTitle = (item) => `${item.title} - Hello world`;
    const assocTitle = (item) => assoc('title', itemTitle(item), item);
    
    const deviceTypeFilter = curry(
      (filterTypes, items) => filter(
        propSatisfies(contains(R.__, filterTypes), 'type'), 
        items
      )
    );
    
    const filterByTypeWithTitle = (filterTypes, devices) => pipe(
      deviceTypeFilter(filterTypes),
      map(assocTitle)
    )(devices)
    
    
    const result = filterByTypeWithTitle([deviceTypes.watch, deviceTypes.phone], deviceList);
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多