让操作javascript对象数组像.net lamda表达式一样

  随着web应用程序的富客户端化、ajax的广泛使用及复杂的前端业务逻辑。对js对象数组、json数组的各种操作越来越多、越来越复杂。如果处理js对象数组能够像.net lamda一样方便、灵活,这将是一件很美好的事。

  由于最近项目中对json对象数组的操作很多,为了方便开发、使用方便、提高代码的重用性,就对js Array扩展一些类似 .net lamda一样的方法。

我们来先看一个例子

我们知道现在用json作为数据传输方式的太多了,如果返回的json数据如下:

var jsonData=[{Id:1,Name:"name1",Age:11},
  {Id:2,Name:"name2",Age:22},
  {Id:3,Name:"name3",Age:33},
  {Id:4,Name:"name4",Age:22},
  {Id:5,Name:"name5",Age:32},
  {Id:6,Name:"name6",Age:22}];

需求一、查找Age大于22岁的我们应该怎么做?当然我们自然为然的会想到如下的做法,代码如下:

function queryData(list)
{
var arr=[];
for(var i=0;i<list.length;i++)
{
var item=list[i];
if(item.Age>22)
{
arr.push(item);
}
}
return arr;
}

这样做就实现了我们想要的功能,但是如果又有一个需求

需求二、查找 Age小于22岁呢?当然也能实现,代码如下:

function queryData2(list)
{
var arr=[];
for(var i=0;i<list.length;i++)
{
var item=list[i];
if(item.Age<22)
{
arr.push(item);
}
}
return arr;
}

这时我们有没有发现只是一个查询判断逻辑的不同我们就又要写一个方法并且写着重复的 for循环,这样重复的代码太令人讨厌了(不好的地方就不一一说了)。再想想.net中对数据的各种不同逻辑的查找一个lamda表达式就解决了,js中是否能像.net lamda表达式一样解决不同逻辑的查询、能不能把重复的代码提取出来呢?

这当然可以了我们都应该知道.net lamda的主要核心就是利用匿名函数。刚才需求一、需求二查找数据时主要的不同是查询逻辑的判断,那么我们把查询时逻辑判断那段代码用匿名函数传进方法里,重复的for循环放到函数里不就能实现了我们想要的吗?代码如下:

function findData(list,fn)
{
var arr=[];
for(var i=0;i<list.length;i++)
{
var item=list[i];
if(fn(item))
{
arr.push(item);
}
}
return arr;
}

如上代码,它不仅仅能满足需求一,需求二,而且还能满足查找Age等于22的数据,Age大于30等等各种需求。

上面的findData函数已经能满足各种是查询要求了,我们还可以对其优化让它更好用,更类似lamda表达式,代码如下:

Array.prototype.FindAll = function (fn) {
for (var i = 0, len = this.length; i < len; i++) {
var o = this[i];
if (fn.call(o, o)) {
arr.push(o);
}
}
return arr;
};

这样我们调用函数时就可以这样用了:

var data=jsonData.FindAll(function(){return this.Age>22;});//利用call调用函数,不知道的可以查找了解

var data=jsonData.FindAll(function(m){return m.Age>22;});

是不是类似我们的lamda表达式的用法,而且代码很简单、优雅、也能满足各种查询要求

以查询为例对Array扩展出FindAll函数,当然我们也可以根据自己的需要扩展出自己要用到的函数。

下面是项目中用到的几个函数的扩展,注视已经很清楚了,大家慢慢看吧!

代码如下:

/*
函数:向对象数组中添加对象数组
参数:对象数组或单个对象
返回:返回添加后的对象数组
调用方式:var result=list.Add({Id:66,Age:66});
var result=list.Add([{Id:66,Age:66},{Id:77,Age:77}]);
*/
if (Array.prototype.Add && typeof Array.prototype.Add == "function") {
alert("Array.prototype.Add 函数已存在,不能再次添加");
} else {
Array.prototype.Add = function (obj) {
obj instanceof Array ? this.push.apply(this, obj) : this.push.call(this, obj);
return this;
};
} /*
函数:根据条件从对象数组中获取一个对象
参数:匿名函数,字段,值
返回:查找到的对象,如果没有查找到返回null
调用方式:var result=list.FindOne(function (o) { return o.Age>30; });
var result=list.FindOne(function () { return this.Age>30; });
var result=list.FindOne("Age",22);
*/
if (Array.prototype.FindOne && typeof Array.prototype.FindOne == "function") {
alert("Array.prototype.FindOne 函数已存在,不能再次添加");
} else {
Array.prototype.FindOne = function (property, value) {
var fn = typeof property === "function" ? property : function () { return this[property] == value; };
for (var i = 0, len = this.length; i < len; i++) {
var o = this[i];
if (fn.call(o, o)) {
return o;
}
}
return null;
};
} /*
函数:根据条件查询对象数组
参数:匿名函数;字段,值
返回:查找到的对象数组
调用方式:var result=list.FindAll(function (m) { return m.Age>30; });
var result=list.FindAll(function () { return this.Age>30; });
var result=list.FindAll("Age",22);
*/
if (Array.prototype.FindAll && typeof Array.prototype.FindAll == "function") {
alert("Array.prototype.FindAll 函数已存在,不能再次添加");
} else {
Array.prototype.FindAll = function (property, value) {
var arr = [], fn = typeof property === "function" ? property : function () { return this[property] == value; };
for (var i = 0, len = this.length; i < len; i++) {
var o = this[i];
if (fn.call(o, o)) {
arr.push(o);
}
}
return arr;
};
} /*
函数:将对象数组中的每个对象投影到新的对象中
参数:匿名函数
返回:返回新的对象数组
调用方式:var result=list.Select(function () { return {Id=this.Id,Age:this.Age}; });
var result=list.Select(function (m) { return {Id=m.Id,Age:m.Age}; });
var result=list.Select(function () { return this.Id==2?{Id=m.Id,Age:m.Age}:null; });
*/
if (Array.prototype.Select && typeof Array.prototype.Select == "function") {
alert("Array.prototype.Select 函数已存在,不能再次添加");
} else {
Array.prototype.Select = function(fn) {
var arr = [];
for (var i = 0, len = this.length; i < len; i++) {
var o = this[i];
var one = fn.call(o, o);
if (!Em.IsNull(one)) {
arr.push(one);
}
}
return arr;
};
} /*
函数:从对象数组中删除符合条件的对象
参数:匿名函数;字段,值
返回:返回删除后的对象数组
调用方式:var result=list.Del(function (m) { return m.Age>30; });
var result=list.Del(function () { return this.Age>30; });
var result=list.Del("Age",22);
*/
if (Array.prototype.Del && typeof Array.prototype.Del == "function") {
alert("Array.prototype.Del 函数已存在,不能再次添加");
} else {
Array.prototype.Del = function (property, value) {
var fn = typeof property === "function" ? property : function () { return this[property] == value; };
for (var i = 0; i < this.length; i++) {
var o = this[i];
if (fn.call(o, o)) {
this.splice(i, 1);
i--;
}
}
return this;
};
} /*
函数:计算数组对象中某列的和,如果是简单数组直接把数组每项是数字的相加
参数:求各的对象列名
调用方式:var sumValue=ArrayData.Sum("Age");
var sumValue=ArrayData.Sum();
返回:求和的结果
*/
if (Array.prototype.Sum && typeof Array.prototype.Sum == "function") {
alert("Array.prototype.Sum 函数已存在,不能再次添加");
} else {
Array.prototype.Sum = function(coloumName) {
var sumValue = 0, i = this.length;
var fn = coloumName ? function() {return isNaN(this[coloumName]) ? 0:this[coloumName];} : function() {return isNaN(this) ?0:this;};
for (; i--;) {
var o = this[i];
sumValue+=Number(fn.call(o, o));
}
return sumValue;
};
}

以上就是主要的内容,当然最重要的是大家有什么好的、不好的想法与意见,

可以尽情的拍砖,以之于能够有更高效、优雅的实现方式!

让操作javascript对象数组像.net lamda表达式一样的更多相关文章

  1. ajax操作之操作 JavaScript 对象

    通过请求获取充分格式化的HTML虽然很方便,但这也意味着必须在传输文本内容的同时也 传输很多HTML标签.有时候,我们希望能够尽量少传输一些数据,然后马上处理这些数据.在 这种情况,我们希望取得能够通 ...

  2. Javascript 对象 - 数组对象

    JavaScript核心对象 数组对象Array 字符串对象String 日期对象Date 数学对象Math 数组对象 数组对象是用来在单一的变量名中存储一系列的值.数组是在编程语言中经常使用的一种数 ...

  3. ArrayList的操作和对象数组

    ArrayList是List接口的一个实现类,它是程序中最常见的一种集合. ArrayList内部的数据存储结构时候数组形式,在增加或删除指定位置的元素时,会创建新的数组,效率比较低,因此不适合做大量 ...

  4. Ajax 向后台提交一个 JavaScript 对象数组?

    var postArray= new Array(); var temp = new Object(); temp.id='1'; temp.name='test'; postArray.push(t ...

  5. 对JavaScript对象数组按指定属性和排序方向进行排序

    引子 在以数据为中心的信息系统中,以表格形式展示数据是在常见不过的方式了.对数据进行排序是必不可少的功能.排序可以分为按单个字段排序和按多个字段不同排序方向排序.单字段排序局限性较大,不能满足用户对数 ...

  6. JavaScript对象数组根据某属性sort升降序排序

    1.自定义一个比较器,其参数为待排序的属性. 2.将带参数的比较器传入sort(). var data = [    {name: "Bruce", age: 23, id: 16 ...

  7. 浅谈JavaScript对象数组根据某属性sort升降序排序

    1.自定义一个比较器,其参数为待排序的属性. 2.将带参数的比较器传入sort(). var data = [ {name: "Bruce", age: 23, id: 16, s ...

  8. javascript中的Array对象 —— 数组的合并、转换、迭代、排序、堆栈

    Array 是javascript中经常用到的数据类型.javascript 的数组其他语言中数组的最大的区别是其每个数组项都可以保存任何类型的数据.本文主要讨论javascript中数组的声明.转换 ...

  9. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

随机推荐

  1. angularjs directive 实例 详解

    前面提到了angularjs的factory,service,provider,这个可以理解成php的model,这种model是不带html的,今天所说的directive,也可以理解成php的mo ...

  2. js判断上传文件的类型和大小

    //检测文件大小和类型 function fileChange(target){ //检测上传文件的类型 if(!(/(?:jpg|gif|png|jpeg)$/i.test(target.value ...

  3. Nginx 内置变量,细化规则,真实IP获取及限制连接请求

    希望下周测试之后能用起来!!!感觉很有用的. http://www.bzfshop.net/article/176.html http://www.cr173.com/html/19761_1.htm ...

  4. CentOS 6.5配置nfs服务

    CentOS 6.5配置nfs服务 网络文件系统(Network File System,NFS),一种使用于分散式文件系统的协议,由升阳公司开发,于1984年向外公布.功能是通过网络让不同的机器.不 ...

  5. 转:Asp.Net MVC中DropDownListFor的用法

    在Asp.Net MVC中可以用DropDownListFor的方式来让用户选择已定列表中的一个数值.用法不复杂,这里简单做一个记录. 首先我们要定义一个 Model ,用户在 DropDownLis ...

  6. structs2使用小结2

    回顾之前做过类似structs2的知识点总结 Structs2历史.处理流程及与1.0版本的区别 Structs2配置文件.拦截器.校验等 EL表达式在JS中使用 ${}El表达式不能直接在单独JS文 ...

  7. 如何实现异步调用WCF

    在面向服务的.NET开发中,我们经常要调用WCF服务加载数据,这时候,如果使用同步调用,会阻止UI,影响用户体验UE/UX,而且当服务器ping不通或者网速特别烂的情况下,这时候基本上是处于卡死状态, ...

  8. Swap Nodes in Pairs 解答

    Question Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1 ...

  9. batch 批处理获取系统时间

    文件test.bat,内容命令如下: @echo off set filename=%,%-%,%-%,% %,%:%,%:%,% echo %filename% pause

  10. [转载]用可变参数宏(variadic macros)传递可变参数表

    注意:_VA_ARGS__ 从VS2005才开始支持 在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如: #define pr_debug(fmt,arg...) printk(KER ...