任逍遥

 找回密码
 立即注册
查看: 30828|回复: 99

自从用了linqjs,再也不用担心操作json集合啦

    [复制链接]
  • TA的每日心情

    2020-9-5 20:20
  • 签到天数: 487 天

    连续签到: 1 天

    [LV.9]妙领天机

    530

    主题

    3430

    帖子

    4571

    积分

    如雷贯耳

    Rank: 8Rank: 8

    积分
    4571
    发表于 2018-7-23 21:38:07 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x

      引言
      前几天做博客项目的时候,想用ajax实现一个文章评论的无限递归加载效果,针对一个从后端返回的json数据数据,首先想到的是递归遍历,但是js的递归写法开始着实让我头晕,所以在寻思有没有更好的解决方案可以实现这个递归加载,不料一个天真的想法出现在脑海里:C#有Lambda表达式,js也有Lambda表达式,那js会不会有像C#那样操作数据集的linq写法,或者js有没有像C#里面的Enumerable这样的数据结构,经过了搜索引擎的验证以后,卧槽,js还真有这样的东东,这下爽了,可以在js里面用linq了——linq.js类库,果然真是高手在民间啊,再也不用担心js操作复杂的json数组了。
      Linq.js官方的介绍中说支持90多个方法,我觉的起码是C# Linq有的方法它肯定有。
      什么是Linq.js?
      C# 3.0推出了.Net独有的新特性:Linq。自从有了Linq,前端工程师再也不用担心对集合的操作了。同理,Linq to js 当然也就是对前端集合变量进行操作的一种技术框架。
      哟,C#开发者这下肯定爽坏了,那java、php、Python是不是没戏?错!这跟你用什么语言没什么关系,只要你会敲js代码就好。跟着下面的节奏,一起来体验linq吧!
      Linq.js官网
      因为是前端框架,所以你懂得,只需要引用一个js文件即可。官网上面有文件和Demo,可以上去看看。
      使用方式主要有两种:
      使用方法一、直接引用js文件;
      使用方法二、使用Nuget安装Linq to js。或在PM安装控制台中输入Install-Package jslinq。
      使用方法三、CDN引入:<script src="https://cdn.bootcss.com/linq.js/2.2.0.2/linq.js"></script>
      本篇以Linq to js的lamada表达式写法的方式来以此介绍常用方法。
      Linq.js初体验
      首先来构造一堆的假数据:
      var myList = [
      { Name: "Jim", Age: 20 },
      { Name: "Kate", Age: 21 },
      { Name: "Lilei", Age: 18 },
      { Name: "John", Age: 14 },
      { Name: "LinTao", Age: 25 }
      ];
      (1)条件查询:Where
      var arrRes = Enumerable.From(myList).Where(x=>x.Name=='Jim').ToArray();
      arrRes的结果为[{"Name":"Jim","Age":20}],相当于执行了SQL语句:select * from myList where Name=’Jim’;
      我们来看看这种写Lamada表达式的原型:
      var arrRes = Enumerable.From(myList).Where(function (i) { return i.Name == 'Jim'; });
      参数i是对应的集合里面的实体模型,返回类型为bool类型。有没有和C#里面的扩展函数Where的定义很像(不懂C#的到这儿可能会不知所云,那就跳过吧):
      public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
      参数Func<TSource, bool> predicate为匿名委托,需要传入实体模型TSource,然后返回值为bool类型。其实感觉linq to js的使用就是参照c#里面的定义来的。
      (2)条件选择:Select
      var arrRes = Enumerable.From(myList).Select(x=>x.Age*10).ToArray();
      arrRes得到结果[200,210,180,140,250]
      ,相当于执行了SQL语句:select Age from myList;
      (3)排序、去重:OrderBy、Distinct
      var arrRes = Enumerable.From(myList).OrderBy(x=>x.Age).ToArray();//降序OrderByDescending()
      得到的结果会按照Age排序。
      var arrRes = Enumerable.From(myList).Distinct(x=>x.Age).ToArray();
      得到的结果集合的数量为3个:[ { Name: "Jim", Age: 20 }, { Name: "John", Age: 14 }, { Name: "LinTao", Age: 25 }]。
      (4)遍历:ForEach
      Enumerable.From(myList).ForEach(function (value, index) {
      document.write("值=" + value + ",索引=" + index);
      });
      很显然两个参数:一个是值,另一个是当前索引,就不上图了。
      (5)取唯一对象:First、FirstOrDefault、Last、LastOrDefault、Single、SingleOrDefault
      var arrRes = Enumerable.From(myList).FirstOrDefault(x=>x.Age>18);//取第一个年龄大于18 的
      其他几个用法和这个类似。这个没什么好说的。关于方法名带default的,下面给出了详细说明:
      操作符
      如果源序列是空的
      源序列只包含一个元素
      源序列包含多个元素
      First
      抛异常
      返回该元素
      返回第一个元素
      FirstOrDefault
      返回default(TSource)
      返回该元素
      返回第一个元素
      Last
      抛异常
      返回该元素
      返回最后一个元素
      LastOrDefault
      返回default(TSource)
      返回该元素
      返回最后一个元素
      Single
      抛异常
      返回该元素
      抛异常
      SingleOrDefault
      返回default(TSource)
      返回该元素
      抛异常
      (6)Skip、Take
      Enumerable.Range(1, 10).Skip(5)//结果[6,7,8,9,10]
      Enumerable.Range(1, 10).Take(5)//结果[1,2,3,4,5]
      (7)取交集、取差集、合并
      var array1 = [1, 412, 5, 3, 5, 412, 7];
      var array2 = [20, 12, 5, 5, 7, 310];
      Enumerable.From(array1).Except(array2)
      //结果3,412,1
      var array1 = [1, 412, 5, 3, 5, 412, 7];
      var array2 = [20, 12, 5, 5, 7, 310];
      Enumerable.From(array1).Intersect(array2)
      //结果5,7
      var array1 = [1, 412, 5, 3, 5, 412, 7];
      var array2 = [20, 12, 5, 5, 7, 310];
      Enumerable.From(array1).Union(array2)
      //结果是两个结果集里面所有值,并自动去重
      当然还有其他一些不常用的方法。有兴趣可以查看文档。其实linq to js还有一种支持jquery的写法。如下:
      Enumerable.Range(1, 10).Where($%2==0)
      //等价于
      Enumerable.Range(1, 10).Where(x=>x%2==0)
      但引用文件的时候需要引用jquery.linq.js这个文件。就是写法不同,效果完全一样,选哪一种就是习惯问题了。博主更加倾向lamada方式的写法,因为和C#用法可以保持一致。
      Linq.js的复杂操作1. 简单的方法链操作
      Enumerable.Range(1, 10)//产生1-10的10个整数
      .Where(i % 3 == 0)//将能被3整除的挑出来
      .Select(i * 10)//把挑出来的结果10倍
      .ToArray()//将Enumerable对象转换成Array对象
      .forEach(function (i) {//遍历数组
      document.write(i + ";"); //30;60;90;
      });
      2. 复杂的方法链操作
      var jsonArray = [
      { "StuID": 1, "StuName": "James", "Age": 30, "Country": "USA" },
      { "StuID": 2, "StuName": "Byant", "Age": 36, "Country": "USA" },
      { "StuID": 3, "StuName": "Lin", "Age": 30, "Country": "Taiwan" },
      { "StuID": 4, "StuName": "Yao", "Age": 30, "Country": "Shanghai" },
      { "StuID": 5, "StuName": "James", "Age": 30, "Country": "USA" },
      { "StuID": 6, "StuName": "Byant", "Age": 36, "Country": "USA" },
      { "StuID": 7, "StuName": "Lin", "Age": 30, "Country": "Taiwan" },
      { "StuID": 8, "StuName": "zhangsan", "Age": 30, "Country": "China" },
      ];//又一堆假数据
      var querResult = Enumerable.From(jsonArray)
      .Where(x.Age <= 30)//筛选
      .Distinct(x=>x.StuName)//去重
      .OrderBy(x.StuID)//排序
      .Skip(0)//跳过0条
      .Take(2)//取2条
      .Select(x=>{x.StuID,x.StuName,x.Age,x.Country})//投影
      .forEach(function (i) {//遍历
      document.write(i.StuID + ";" + i.StuName + ";" + i.Age + ";" + i.Country + "");
      });
      3. Alternate、Contains
      Enumerable.Range(1, 5).Alternate('*').ForEach(function (i) {
      document.write(i + ";"); //;*;2;*;3;*;4;*;
      });
      var r = Enumerable.Range(1, 5).Contains(3);
      document.write(r); //ture
      4. Min、Max
      var max = Enumerable.Range(1, 5).Max(); //5
      var min = Enumerable.Range(1, 5).Min(); //1
      document.write(max + ";" + min);//5;1
      总结
      能用到这些js的地方有些功能在后台也可以实现,但是我个人更喜欢js的方式,所以就用了上面几个方法,另外看看linq.js的源码对一些算法也能加深理。使用情况和爱好根据个人爱好来定,不过当我找到这个框架时着实有些震撼。
    楼主热帖
  • TA的每日心情

    2019-8-30 03:06
  • 签到天数: 470 天

    连续签到: 4 天

    [LV.9]妙领天机

    3

    主题

    2931

    帖子

    2932

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2932
    发表于 2018-7-23 21:44:52 | 显示全部楼层
    支持,赞一个
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 15:07
  • 签到天数: 470 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    2877

    帖子

    2880

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2880
    发表于 2018-7-24 17:55:39 | 显示全部楼层
    支持楼主,用户楼主,楼主英明呀!!!
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-8-30 11:02
  • 签到天数: 471 天

    连续签到: 6 天

    [LV.9]妙领天机

    5

    主题

    2846

    帖子

    2850

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2850
    发表于 2018-7-25 16:49:30 | 显示全部楼层
    不错 支持一个了
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 08:03
  • 签到天数: 476 天

    连续签到: 2 天

    [LV.9]妙领天机

    4

    主题

    2932

    帖子

    2935

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2935
    发表于 2018-7-26 19:42:04 | 显示全部楼层
    支持,楼下的跟上哈~
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-8-30 05:11
  • 签到天数: 462 天

    连续签到: 1 天

    [LV.9]妙领天机

    1

    主题

    2851

    帖子

    2852

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2852
    发表于 2018-7-28 20:34:10 | 显示全部楼层
    支持,赞一个
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 09:06
  • 签到天数: 474 天

    连续签到: 3 天

    [LV.9]妙领天机

    3

    主题

    2940

    帖子

    2935

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2935
    发表于 2018-7-29 06:02:33 | 显示全部楼层
    佩服佩服!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 15:35
  • 签到天数: 461 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    2987

    帖子

    2988

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2988
    发表于 2018-7-29 12:23:53 | 显示全部楼层
    没人回帖。。。我来个吧
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2019-8-30 14:07
  • 签到天数: 472 天

    连续签到: 1 天

    [LV.9]妙领天机

    0

    主题

    2931

    帖子

    2927

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2927
    发表于 2018-7-29 20:57:10 | 显示全部楼层
    回个帖子,下班咯~
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 19:16
  • 签到天数: 484 天

    连续签到: 5 天

    [LV.9]妙领天机

    0

    主题

    2900

    帖子

    2895

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2895
    发表于 2018-7-30 18:38:04 | 显示全部楼层
    围观 围观 沙发在哪里!!!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|任逍遥

    GMT+8, 2024-5-5 21:27 , Processed in 0.078164 second(s), 49 queries .

    Powered by 任逍遥 X3.4

    Copyright © 2001-2023, Rxiaoyao Cloud.

    快速回复 返回顶部 返回列表