瘦人说

Mr.Array

Mr.Array主要用于JavaScript数组操作的扩展,其中很多API类似于underscore.js,你也可以说我山寨了它的数组操作部分,不过我的API中没有用像underscore.js或者JavaScript1.6中的map, filter, every, forEach, some等命名,取而代之的是C#中Enumerable静态类中的select, where, all, any, orderBy, groupBy等,当然如果当前浏览器支持原生方法的话,我会调用原生方法。

Mr.Array可以让开发人员尽可能高效的进行集合操作,LINQ链式语法也可以大大改善编写代码的舒适性,虽然整个扩展很简单,但它确实是很有用的。

当前支持的方法有:

  • 筛选、遍历操作
    • select :  function(predicate)
      根据指定的处理方式predicate处理集合中每个元素并存入新的集合返回,同JavaScript1.6中map操作
    • selectMany :  function(predicate)
      根据指定的处理方式predicate遍历每个元素,返回类型必须为集合,返回值存入新的集合返回
    • toDictionary :  function(keySelector, valueSelector)
      根据keySelectorvalueSelector处理集合中每个元素得到键和值,返回新的键值对对象
    • where : function(predicate)
      根据指定过滤方式predicate对原集合中元素进行过滤,返回过滤后的集合。同JavaScript1.6中filter操作
    • orderBy : function(predicate)
      对集合进行排序,排序方式需指定
    • groupBy : function(predicate)
      对集合进行分组,分组方式需指定
    • any :  function(predicate)
      判断是否符合predicate规则的元素,有就返回true,反之为false。同JavaScript1.6中some操作
    • all :  function(predicate)
      判断是否集合内所有元素都符合predicate规则,符合返回true,反之为false。同JavaScript1.6中every操作
    • take :  function(length)
      返回当前集合中的前length个元素
    • skip :  function(length)
      返回当前集合跳过length个元素之后的元素集合
    • each :  function(predicate)
      遍历当前集合
    • reduce_ltr :  function(predicate)
      从左到右根据predicate指定的方式处理集合中的每个元素,把处理结果和成最终的一个值。同JavaScript1.8中reduce操作
    • reduce_rtl :  function(predicate)
      从右到左根据predicate指定的方式处理集合中的每个元素,把处理结果和成最终的一个值。同JavaScript1.8中reduceRight操作
  • 集合操作
    • except :  function(array)
      差集
    • intersect :  function(array)
      交集
    • union :  function(array)
      并集
    • diff :  function(array)
      两个集合的差异,如[1, 2, 3] 和[2, 3, 4]的差异就是[1, 4]
    • contains :  function(obj)
      判断集合是否包含一个元素
    • containsAll :  function(array)
      判断集合是否包含另一个集合中的所有元素

以上方法都是扩张了数组原型,支持链式调用的同时也支持静态方法调用,引入Mr.array.js文件之后,无论是在浏览器,还是在Nodejs上,全局Mr对象会多一个属性叫作Array,此对象上包含所有以上方法的静态方法。以下方式都是可行的:

链式调用

[4, 3, 1, 2].where(function(o){ return o <= 3; })
     .orderBy(function(a, b){ return a - b; })
     .select(function(o){ return ++o; });
// => [2, 3, 4]

静态方法

var afterWhere =
     Mr.Array.where([4, 3, 1, 2], function(o){
         return o <= 3;
     });
var afterOrder =
     Mr.Array.orderBy(afterWhere, function(a, b){
          return a - b;
     });
var afterSelect =
     Mr.Array.select(afterOrder, function(o){
         return ++o;
     });
// => [2, 3, 4]

毫无疑问链式调用要爽的多,就是漫天的function关键字比较恶心,如果有lambda表达式的话就更加漂亮了,用CoffeeScript享受整个编写过程。

CoffeeScript实现

[4, 3, 1, 2].where((o) -> o >= 3)
     .orderBy((a, b) -> a - b)
     .select((o) -> ++o);
// => [2, 3, 4]

如果是在Nodejs中使用的话,

var array_ext = require('./Mr.array.js');

得到的array_ext就是全局对象,它的所有方法都作为静态方式调用,但是require的过程中已经对数组原型进行扩展,所以链式调用也是可行的。

Testing
我对Mr.Array进行了单元Testing,用的是QUnit,目前只有32个用例,如果有想到新的我也继续更新。代码可以test.js之后看到。

Github
如果你觉得有意义的话,请关注https://github.com/winsonwq/Mr.Array,README持续更新中。FYI,目前用Google Closure Compiler 编译后的大小由8K变为4K。

Comments

Proudly published with Hexo