
https://github.com/wm123450405/linqjs
https://gitee.com/wm123450405/linqjs (国内)
- 对 Javascript 中原生数组、对象进行扩展, 提供了一些对数据的操作方法.
- 包括对数组结构、树形结构、对象结构等数据进行 查询,排序,连接,合并,分组,分段,转换,遍历 等一系列功能.
- 可以用精炼和易懂的代码实现比较复杂的操作
let array = [ 'zhao', 'qian', 'sun', 'li', 'zhou', 'wu', 'zheng', 'wang' ] //将上述数组按照字母长度进行排序, 字母长度一致的按照字母顺序倒序排序 console.log(array.asEnumerable().orderBy(str => str.length).thenByDescending().toArray()); //结果为 //wu,li,sun,zhou,zhao,wang,qian,zheng //一些人 let magnus = { name: "Hedlund, Magnus" }, terry = { name: "Adams, Terry" }, charlotte = { name: "Weiss, Charlotte" }; //一些宠物 let barley = { name: "Barley", owner: "Adams, Terry" }, boots = { name: "Boots", owner: "Adams, Terry" }, whiskers = { name: "Whiskers", owner: "Weiss, Charlotte" }, daisy = { name: "Daisy", owner: "Hedlund, Magnus" }; //一个包含所有 人 的数组 let people = [ magnus, terry, charlotte ]; //一个包含所有 宠物 的数组 let pets = [ barley, boots, whiskers, daisy ]; //这是一个一对多关系的两个数组 //需要显示出来所有的 人-宠物 的关系信息 //传统做法是 for (let p of people) { for (let pet of pets) { if (pet.owner === p.name) { console.log(`${ p.name } - ${ pet.name }`); } } } //使用我的工具是 //思想类似数据库查询(如下语句), 连接两个数组(表), 条件为 person 的 name 与 pet 的 owner 相等 //select person.name, pet.name from `people` as person join `pets` as pet on person.name = pet.owner people.asEnumerable() .join(pets, (person, pet) =>`${ person.name} - ${ pet.name}`, person => person.name, pet => pet.owner) .forEach(res => console.log(res)); //这是一个树形结构 let tree = { value: 'a', children: [ { value: 'b', //此节点为 节点 c 与 节点 f 的最小公共祖先 children: [ { value: 'c' }, { value: 'd', children: [ { value: 'e' }, { value: 'f' }, { value: 'g' }, ] } ] }, { value: 'h', } ] }; //获取一个树形的中多个节点的最小公共祖先 let root = tree.asEnumerable(node => node.children, node => node.value); console.log(root.lowestAncestor('c', 'f')); //结果是 b 更多用法及案例 希望大家进入文档查看 http://wm123450405.oschina.io/linqjs/#/zh-cn
望大家多多关注 并给于意见和指导 谢谢
1 wm123450405 OP 一开始,在 ES5 的时代,我觉得 js 对数组的操作实在太繁琐了. 可能正是这种繁琐才有了像 underscore 这样优秀的 js 库的出现. 我本不是做前端出身的,我觉得其他语言对于数组或列表的操作要比 js 好用很多,提供了大量的方法和功能. 于是最早参考的 C#中的功能实现了一些方法. 后来,ES6 发布并普及开来,js 原生数组也增加了很多好用的功能,但是这还远远不够. 于是我又翻出了我的代码用 ES6 重写.这一次我又借鉴了另外一些语言中的部分特性,比如 php.我想我后面可能再会添加一些其他语言类似的功能,比如 Java 等. 后来我在 stackoverflow 中看到很多人对于树形结构的操作提了很多的问题,我像我的工具包应该要可以为他们提供帮助.于是在最新的几个版本中我加入了对树形结构的一些操作. 我想现在这个工具包应该算比较稳定了. 所以我发上来希望和大家交流交流. 也希望能学到更多的东西. |
2 codermagefox Mar 29, 2018 楼主你好,请问我能抄一个自己做实现吗? |
![]() | 3 per Mar 29, 2018 via iPhone @wm123450405 没看代码,不过你这个是在数据类型的 prototype 上修改的吗? |
4 wm123450405 OP @per 是的 在 prototype 上做了扩展的 |
5 wm123450405 OP @codermagefox 可以啊 我也是造了一些轮子而已 |
6 codermagefox Mar 29, 2018 @wm123450405 #5 准备看完 underscore 再来看你这个,然后自己撸个试试。感谢,已 star |
7 per Mar 29, 2018 via iPhone @wm123450405 那我这里有个问题,比如一个数组是由一个类 A 实例化得到的,然后这个 A 也是继承于其他类,那当访问你的这个方法的时候会通过原型链一层层往上找,考虑过开销嘛? |
8 crs0910 Mar 29, 2018 |
9 wm123450405 OP @per 不好意思 不是很明白你想表达的意思 你可以举例说明下嘛 我这里只是扩展了 Array 类 用 Array.prototype 的方式 |
10 wm123450405 OP @crs0910 你是让我看看 mootools 这个库吗? 如果你希望的只是类似 flatMap 这样的展开一个包含数组元素的数组 在我的库里是 selectMany |
11 zenxds Mar 29, 2018 改原生数组的原型后患无穷,ES 标准里的一些方法名那么奇怪就是因为当年 prototype.js 的遗留才不得不改名 |
12 wm123450405 OP @zenxds 我的库默认只会在 Array 上注册一个 asEnumerable 方法 用来获取一个 IEnumerable 对象进行后续操作 当然也可以开启对 Array 的直接扩展 主要看你有没有用到其他有冲突的库 |
13 per Mar 29, 2018 @wm123450405 我表达的不是很清楚,你可以看一下 MDN 上的解释。不过还是给你点个星 |
14 per Mar 29, 2018 |
15 wm123450405 OP @per 感谢你提供的信息. 我想我在编写这个库的时候并没有考虑这一层面的性能问题. 首先你分享的文章我不是特别的明白 我理解的大概含义 一般的 js 引擎会对已有的对象的属性查找进行优化 会将属性按照某种顺序排列在内存中 并生成一个身份(shape 或 structure ID) 如果修改 prototype 的话 会打乱这种顺序 导致原本可以快速查找属性的功能失效 造成性能损失 就你一共提出的问题 我想: 如果说因为原型链比较深导致其查找 property 比较慢的话 我想这个应该不容易避免 因为原型链的深度是受类型的继承关系的影响 如果是因为修改 prototype 导致 js 引擎在做优化时不能达到最佳性能的话 我目前也没有更好的解决办法 |
16 wm123450405 OP 首先感谢各位的关注 如果大家发现有什么问题或者有什么希望加入的功能 欢迎大家在此回复 或者直接在 github/gitee 上提 issue 给我 | ||
17 0x4b0082 Apr 2, 2018 拒绝修改原生数据类型的库:( |
18 narcotics Apr 2, 2018 via Android lodash 的做法是用 _.chain 做一层包装,再实现链式操作,最后用 _.value 做"拆箱" 总之改变原生原型不是个好实践 |
19 wm123450405 OP 回复 楼上 2 位 首先 我的库里目前只对原生对象扩展了 asEnumerable 一个方法. 就是尽量避免冲突 其次 库也支持 Enumerable(source)的方式获取一个和 source.asEnumerable()一样的结果, 类似 lodash 的 chain. 再使用 toArray 等方法生成最终结果. 当然 如果大家觉得修改原生原型的做法确实不合适 我想也我会在后面的版本中修改 /删除这种方式 |