让操作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. CSS3 基础知识

    CSS3 基础知识1.边框    1.1 圆角  border-radius:5px 0 0 5px;    1.2 阴影  box-shadow:2px 3px 4px 5px rgba(0,0,0 ...

  2. jQuery选择器的学习

    jQuery的核心在于它的选择器,通过观看视频和阅读,发现jQuery选择器大体上的分类可分为这么几种(不同人方式不同,这里选择一个自认为比较好的): 1.基础选择器(对应api文档中的基本选择器和层 ...

  3. Scala学习笔记--集合类型Queue,Set

    补充知识:http://www.importnew.com/4543.html 正文开始 scala.collection.immutable scala.collection.mutable 队列Q ...

  4. js给div动态添加控件,然后给这个控件动态添加事件

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  5. 浅谈程序员创业(要有一个自己的网站,最好的方式还是自己定位一个产品,用心把这个产品做好。或者满足不同需求的用户,要有特色)good

    浅谈程序员创业 ——作者:邓学彬.Jiesoft 1.什么是创业? 关于“创业”二字有必要重新学习一下,找了两个相对权威定义: 创业就是创业者对自己拥有的资源或通过努力能够拥有的资源进行优化整合,从而 ...

  6. 《Programming WPF》翻译 第6章 4.应用程序全球化

    原文:<Programming WPF>翻译 第6章 4.应用程序全球化 如果你打算发布你的应用程序到全球各地,你可能需要为不同地区的用户界面准备不同的版本.至少,这需要解决将文本翻译成适 ...

  7. The square chest

    The square chest Sophia pressed the button in front of her, slamming her fist against it. The door r ...

  8. Python开发过程中17个坑

    一.不要使用可变对象作为函数默认值 复制代码代码如下: In [1]: def append_to_list(value, def_list=[]):   ...:         def_list. ...

  9. Direct3D 纹理映射

    纹理映射是将2D的图片映射到一个3D物体上面,物体上漂亮图案被称为纹理贴图, 一个表面可以支持多张贴图等等,下面简单介绍下纹理贴图 纹理贴图UV: 贴图是一个个像素点组成,每一个像素点都由一个坐标最后 ...

  10. Non-negative Partial Sums(单调队列)

    Non-negative Partial Sums Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...