让操作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. 保存BASE64编码图片

    1.前端上传用户图片时,一些K数较小图片,头像图标等 .以bass64编码后的字符串传到服务器. 2.服务器接收并保留到本地. // 页面上点击保存 $.post('/imgupload/save', ...

  2. linux 安装中文支持包及中文字符集配置

    由于某些原因系统安装时未安装中文支持,导致后续应用出现中文方块乱码现象,解决方法很简单,当然不是重装,只需以下三步即可搞定. 1.安装中文包: #yum -y groupinstall chinese ...

  3. Oracle 10.2数据库管理员指南-27章

    27使用调度程序 Oracle Database provides database job capabilities through Oracle Scheduler (the Scheduler) ...

  4. mysql在关闭时的几个阶段

    mysql关闭的大致过程 1.The shutdown process is initiated 初始化关机过程有许多种方法1.mysqladmin shutdown ; 2.kill pid_of_ ...

  5. [iOS常见问题] 关于使用QQ做第三方登录的问题!

    [iOS常见问题] 关于使用QQ做第三方登录的问题! 注意:QQ本身没有授权功能,所以想要使用QQ做第三方登录必须通过QQ空间来实现! 第一步:集成ShareSDK(步骤同集成分享的一样,如果已经集成 ...

  6. discuz@功能的代码

    //转载 $atlist = $atlist_tmp = $ateduids = array(); preg_match_all("/@([^\r\n]*?)\s/i", $mes ...

  7. 猎豹上市(猎豹的广告收入中有70%来自BAT三家公司,总收入中有58%来自BAT)

    发表日期: 2014 年 5 月 9 日 From 网易专题 文/赵楠 村里那点儿事 猎豹移动上市之夜,我挺激动. 激动除了因为有好朋友在这家公司外,也因为猎豹移动在历史上的几次起承转合非常不易,在巨 ...

  8. GET: https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login? loginicon=true &uuid=odcptUu2JA==&tip=0

    GET: https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login? loginicon=true &uuid=odcptUu2JA==&am ...

  9. thinkjs与Fine Uploader的邂逅

        最近在做一个内部系统,需要一个无刷新的上传功能,找了许久,发现了一个好用的上传工具-Fine Uploader,网上也有不少关于它的介绍,对我有不少的启发,结合我的使用场景简单的介绍一下它与t ...

  10. IT人员应该怎么跳槽

    中国的程序员只有两个状态,刚跳槽和准备跳槽.   中国IT行业的快速发展对IT从业人员的需求不断扩大,记得08年刚毕业的时候,在帝都找一个3k的工作都让我特别满足,现在仅能写出”hello world ...