【发布时间】:2016-12-29 23:20:20
【问题描述】:
我正在编写一个小实用函数来将字符串从一种单词分隔方案转换为另一种。整个项目使用lodash,我知道它带有_.camelCase 之类的东西,但我觉得不利用那些方案转换助手更具可扩展性。
这个想法是其他开发人员可以轻松地将他们自己的方案定义添加到我已经拥有的方案定义中:
const CASES = [
{name: 'lower_kebab', pattern: /^[a-z]+(_[a-z]+)*$/g,
to_arr: w=> w.split('_'),
to_str: a=> a.map(w=>w.toLowerCase()).join('_')},
{name: 'UpperCamel', pattern: /^([A-Z][a-z]*)+$/g,
to_arr: w=> w.match(/[A-Z][a-z]*/g),
to_str: a=> a.map(_.capitalize).join('')},
//...
];
所以每个Case 都需要一个模式来确定一个字符串是否属于该方案,一个to_arr 来适当地分割字符串,一个to_str 来将一个单词数组加入到该方案的字符串中(@ 987654327@ 是可选的,但最好是描述性的)。我已将这两个包括在内,因为它在从 lower_kebab 到 UpperCamel 的转换中出现了一些意外行为。
我已经像这样实现了实际的转换功能:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.3/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.3/lodash.fp.min.js"></script>
<script>
$(document).ready(()=>{
var CASES = [
{ name: 'lower_kebab', pattern: /^[a-z]+(_[a-z]+)*$/g,
to_arr: w=> w.split('_'),
to_str: a=> a.map(w=>w.toLowerCase()).join('_')
},
{ name: 'UpperCamel', pattern: /^([A-Z][a-z]*)+$/g,
to_arr: w=> w.match(/[A-Z][a-z]*/g),
to_str: a=> a.map(_.capitalize).join('')
},
//...
];
function convert_to(target_scheme_example){
return _.compose(
CASES.find(c=>c.pattern.test(target_scheme_example)).to_str
, str=> CASES.find(c=>c.pattern.test(str)).to_arr(str) );
}
$('#go').on('click', ()=> $('#result').text(
convert_to( $('#dst').val() )( $('#src').val() )
));
});
</script>
<p>Try "<strong>UpperCamel</strong>" to "<strong>lower_kebab</strong>" and vice-versa.</p>
<input id="dst" value="UpperCamel" placeholder="Example of target scheme">
<input id="src" value="lower_kebab" placeholder="String to convert">
<button id="go">Convert</button>
<div>
<p><strong>Result:</strong></p>
<p id="result"></p>
</div>
“真实”版本严格存在于服务器端代码中,因此 sn-p 中所有与 DOM 相关的内容纯粹用于演示目的(“真实”版本还使用 _.get 进行了一些错误检查为简洁起见,我在这里排除了)。
这就是事情变得奇怪的地方。
在服务器端,问题表现为convert_to('UpCa')('activity_template') 评估为"Activity_template" 和"activity template" 之类的东西。在演示 sn-p 中,我相信同样的问题表现为只能单击“转换”一次而不会引发异常。
有什么想法吗?我的正则表达式有点不对劲吗?我是否误解了如何使用_.compose?如果工具只是坏了,那将是一回事,但它确实让我对它在许多情况下的工作方式感到困惑,但不是全部。
【问题讨论】:
-
CASES.find(c=>c.pattern.test(target_scheme_example)).to_str不保留任何关于 Javascript 中对象的to_str方法的任何信息。不过,您的to_strs 似乎不需要该信息。 -
我假设
compose(或者更确切地说,compose的结果)会这样做,即,为了运行f(g(x)),我需要保留f和g。有没有什么好的方法可以达到这个效果? -
您是否期望
_.compose(f, g)在g之前应用f?看起来您对此有所期待。 -
我可以看到它的样子,但我认为我的构图顺序是正确的。要应用的第一个函数(
compose的最后一个参数)应该是f:String->Array,这是to_arr的签名。第一个论点的类似故事,但to_str -
您在 string->array 部分使用
c=>c.pattern.test(str),这需要str已经匹配模式。也许你把str和target_scheme_example搞混了。
标签: javascript lodash