matchs-js

pattern match


Keywords
match pattern, pattern match, match
License
ISC
Install
npm install matchs-js@1.0.2

Documentation

match.js

模式匹配 类似haskell中模式匹配功能 like haskell pattern match

使用(useage)

node

npm install matchs-js --save

es5

var match = require("matchs-js").match;

>=es6

import {match} from 'matchs-js'

var fn = match({
  '"hello"':"hello",
  '(_:xs)':xs=>xs
});

console.log(fn([1,2,3])) //->[2,3]

brower

只需引入match.js即可(未压缩15k) 无其它依赖

<script src="./match.js"></script> 

简介(desc)

模式匹配,是指将两个模式作为输入,计算模式元素之间语义上的对应关系的过程.

支持javascript中的基本数据类型,数组,对象,函数 以及相应的解构能力.

test

使用jasmine cdn 做单元测试 文件存放路径 ~ /test/match-jasmine-test.html ~

demo

  • 例子中使用了ecmascript6中的部分特性 普通浏览器运行需要改为普通语法 推荐使用chrome

例子存放于 ~ /demo ~ 中 目前还不完善

几段例子代码(snipets)

数组求和

var sum = match({
    "[]":0,
    "(x:xs)":(x,xs)=>x+sum(xs)
});
sum([1,2,3,4,5]);

快速排序

var sort = match({
    "[]":[],
    "(x:xs)":(x,xs)=>sort(xs.filter(a=>a<x)).concat(x).concat(sort(xs.filter(a=>!(a<x))))
});
sort([1,8,0,4,0]);

编写逻辑

  • 如果是数组

** 空数组返回false

** 数组头部值为"string" 返回剩余数组 以字符串形式连接

** 其它情况数组以字符串形式连接

  • 如果是对象

** type为string 返回对象的value属性值

** type为self 返回自身

  • 其它情况返回false
var logicfn = match({
    "[]":false,
    "('string':xs)":xs=>xs.join(""),
    "x?array":x=>x.join(""),
    "{type:'string',value:val}":val=>val,
    "@obj{type:'self'}":obj=>obj,
    "else":false
});

使用文档

基本匹配

match(obj)的方式使用

key代表数据语意描述

val代表匹配结果 如下

var fn = match({
    "777":'number',
    "'str'":'string',
    "[]":'empty arr',
    "{}":'empty obj',
    "else":'else'
});
fn(777)->'number' //匹配"'777'"
fn('str')->'string' //匹配 "'str'"
fn([])->'empty arr' //匹配 "'[]'"
fn({})->'empty obj' //匹配"{}"
fn(8388)->'else'    //匹配"else"

多参数,和参数忽略

匹配多个参数意逗号隔开,_代表忽略这个参数

var fn = match({
    "1":1,
    "1,2":2,
    "1,2,3":3,
    "1,_,3":4,
    "_,_,_":5,
    "else":"else"
});
fn(1)->1        //匹配 "1"
fn(1,2)->2      //匹配 "1,2"
fn(1,2,3)->3    //匹配 "1,2,3"
fn(1,3,3)->4    //匹配 "1,_,3" 
fn(3,3,3)->5    //匹配 "_,_,_"
fn(1,1,1,1,1,1,1)->"else"

变量绑定和数组对象解构

(1:2:[])代表匹配一个数组 第一个元素是1 第二个是2 (x:xs) 匹配一个数组 第一个元素绑定到x 剩余的绑定到xs

{a,b} 代表匹配一个对象 对象key为a的值绑定到a key为b的值绑定到b

var fn = match({
    "(1:xs)":function(xs){return xs},
    "(a:b:c:xs)":function(a,b,c,xs){return [a,b,c,xs]},
    "(x:xs)":function(x,xs){return [x,xs]},
    "{a,b:'b'}":function(a){return a},
    "{a,b}":function(a,b){return [a,b]},
    "{a:{aa},b:'b'}":function(aa,b){return aa},
    "x":function(x){return x}
});
fn([1])->[]                     //匹配 "(1:xs)"
fn([1,2,3])->[2,3]              //匹配 "(1:xs)"
fn([2,2,3])->[2,2,3,[]]         //匹配 "(a:b:c:xs)"
fn([2,2,3,4])->[2,2,3,[4]]      //匹配 "(a:b:c:xs)" 
fn([2,2])->[2,[2]]              //匹配 "(x:xs)"
fn({a:1,b:'b'})->1              //匹配 "{a,b:'b'}"
fn({a:2,b:2})->[2,2]
fn({a:{aa:'aa'},b:'b'})->'aa'
fn(100)->100

?函数

支持自定义函数来匹配 函数返回true表示匹配成功 否则匹配失败 array,object,date,number,string这些函数内置的 用来检查数据类型 自定义函数可传入matchWithFn 第二个参数在当前匹配范围内有效 也可通过 =match.globalScope =使全局有效

也可直接使用全局函数

//全局有效
match.globalScope.testfn=function(a){return a=="test"}
var fn = match({
    "x?array":true,
    "x?object":false,
    "x?testfn":'test'
});
fn([])->true
fn({a:1})->false
fn("test")->'test'
//当前fn有效
var fn = matchWithFn({
    "x?array":true,
    "x?object":false,
    "x?testfn":'test'
}{
  "testfn":function(a){return a=="test"}
});