如何在函数式编程风格中使用reduce来解析YAML前言



我有一个文件想用Javascript解析:

---
title: This is a great title
date: 2012-03-02 11:30:00 -04:00
published: false
---
data_one
data_two
data_three

由此,我只想输出:

['data_one', 'data_two', 'data_three']

所以这意味着我需要跳过前五行。

虽然我可以轻松地让我的脚本自动跳过前五行,但我希望它足够强大,即使其中添加了额外的项目,它也会跳过前言。这是我当前的实现:

const result = rawFileStr.split('n')
  .reduce((acc, item) => {
    const endOfFrontMatter = acc === false && item === '---';
    const isFrontMatter = acc === false || item === '---';
    if (endOfFrontMatter) {
      return [];
    }
    return isFrontMatter ? false : acc.concat(item)
  }, [])

它基本上将累加器设置为 false 以指示它击中第一个---,然后在击中第二个---时,它返回一个空数组。

它有效,但所有这些 if 语句都让我觉得这不是这样做的"功能方式"。有人可以阐明如何使用纯函数式编程来做到这一点吗?

您可以使用

正则表达式按行划分,直到不在第一行的第一---,然后获取其余部分:

const result = rawFileStr.split(/^[^]*?n---n/).pop().split('n');

// Sample data
const rawFileStr = `---
title: This is a great title
date: 2012-03-02 11:30:00 -04:00
published: false
---
data_one
data_two
---
data_three`;
const result = rawFileStr.split(/^[^]*?n---n/).pop().split('n');
console.log(result);

或者,如果没有正则表达式,您可以使用立即调用的函数表达式,该表达式使用第一个---发生的索引之后的项目(不在第一行)对数组进行切片:

const result = (items => items.slice(items.indexOf('---',1)+1))(rawFileStr.split('n'));

// Sample data
const rawFileStr = `---
title: This is a great title
date: 2012-03-02 11:30:00 -04:00
published: false
---
data_one
data_two
---
data_three`;
const result = (items => items.slice(items.indexOf('---',1)+1))(rawFileStr.split('n'));
console.log(result);

您可以通过替换,然后链接到拆分,然后使用过滤器确保不保留空字符串来删除前置内容:

let text = document.querySelector('textarea').value;
let data = text
  .replace(/^---[sS]*?---/, '')
  .split(/s+/)
  .filter(str => str.length);
console.log(data);
<textarea>
---
title: This is a great title
date: 2012-03-02 11:30:00 -04:00
published: false
---
  
data_one
data_two
data_three
</textarea>

最新更新