首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >借助函数柯里化实现读取Markdown元数据

借助函数柯里化实现读取Markdown元数据

作者头像
kifuan
发布2022-10-24 16:25:29
发布2022-10-24 16:25:29
35800
代码可运行
举报
文章被收录于专栏:随便写写-kifuan随便写写-kifuan
运行总次数:0
代码可运行

源码

点击这里前往Github查看本文源码,其中带class的意思就是用了类。

定义

柯里化(英语:Currying) 是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 来源: 维基百科

说白了就是返回函数的函数,其实在开发过程中多半已经用过了,只是之前没有去了解过这个东西叫什么。

我认为,他还可以是被看为一种轻量级的面向对象。

示例

定义一个getAdder函数,返回一个adder

代码语言:javascript
代码运行次数:0
运行
复制
function getAdder(n) {
    return m => n + m
}

const adder = getAdder(3)

console.log(adder(4))
// 7

这便是一种柯里化的应用了。

实际问题

我在开发过程中遇到过这种需求,也就是你现在看到的页面,它是用markdown写成的,并且文件头部有一些元信息,即metadata,本质是一堆键值对,用来描述这个文件。比如当前文件的头部就是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
date: 2022-5-14
category: Learn
tags: JS TS
intro: 返回函数的函数,可以认为是轻量级面向对象
id: 11

我把这个结构抽象一下,改成下面这样:

代码语言:javascript
代码运行次数:0
运行
复制
foo: abc
bar: def

我们的需求就是读取出来这些键值对。

解决方案

代码语言:javascript
代码运行次数:0
运行
复制
function parser(metadata) {
    return key => {
        const prefix = key + ':'
        const data = metadata.find(s => s.startsWith(prefix))

        return data.substring(prefix.length).trim()
    }
}

const parse = parser([
    'foo: abc',
    'bar: def'
])

console.log(parse('foo'))
// abc

console.log(parse('bar'))
// def

可以看出,这里的parser函数就是保存了metadata这一变量内容并且重复使用。

针对于parser函数的执行效率,可以进行以下优化:

代码语言:javascript
代码运行次数:0
运行
复制
function parser(metadata) {
    const map = new Map()
    for (const data of metadata) {
        const [key, value] = data.split(/\s*:\s*/)
        map.set(key, value)
    }
    return key => map.get(key)
}

这里提前把所有的键值对都保存下来了,到执行的时候只需要获取一下即可。

那么回到开头说的,他可以被看成一种轻量级的面向对象,所以说完全可以用到面向对象的方法实现这个功能:

代码语言:javascript
代码运行次数:0
运行
复制
class Parser {
    metadata = new Map()

    constructor(metadata) {
        for (const data of metadata) {
            const [key, value] = data.split(/\s*:\s*/)
            this.metadata.set(key, value)
        }
    }

    parse(key) {
        return this.metadata.get(key)
    }
}

const metadata = [
    'foo: abc',
    'bar: def'
]

const parser = new Parser(metadata)

console.log(parser.parse('foo'))
// abc

console.log(parser.parse('bar'))
// def

但是实际应用中还是通过柯里化的方法更简洁明了,这也正体现这JS这门语言的魅力: 提供多种解决手段,我们总能从中找到较优的解决方案。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码
  • 定义
  • 示例
  • 实际问题
  • 解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档