linq.js - LINQ for JavaScript

这里给大家推荐个js实现的linq,项目地址:mihaifm/linq

使用举例

let strs = ['a', 'b', 'c', 'd', 'e']
Enumerable.from(strs)
    .select((str, index) => ({
        str: str,
        index: index
    }))
    .where(obj => obj.index > 2)
    .forEach(obj => console.log(obj))
//output
//{ str: 'd', index: 3 }
//{ str: 'e', index: 4 }

优点

  • 对于.net开发人员很快就能上手
  • 相比es6的map/reduce额外有更多的方法,如计数、分组、连接、交集差集等,能够更方便的处理数据
//对比统计大于2的number的方式
let data = Enumerable.range(1, 5).toArray()
console.log(
    data.map(num => num > 2 ? 1 : 0)
        .reduce((num1, num2) => num1 + num2)
)
console.log(
    Enumerable.from(data)
        .count(num => num > 2)
)
//output
//3
//3

安装使用

执行npm install linq安装
引入import Enumerable from "linq"(node使用的话,在package.json中配置"type": "module")

一些使用举例

//集合操作
let data1 = [1, 2, 2, 3]
let data2 = [2, 3, 4]
console.log(
    Enumerable.from(data1).distinct().toArray(),                        //去重
    Enumerable.from(data1).concat(Enumerable.from(data2)).toArray(),    //交集不去重
    Enumerable.from(data1).union(Enumerable.from(data2)).toArray(),     //交集并去重
    Enumerable.from(data1).intersect(Enumerable.from(data2)).toArray(), //并集
    Enumerable.from(data1).except(Enumerable.from(data2)).toArray(),    //差集
)
//分组
var data = [
    {
        "date": "2022-08-08 00:15:20",
        "name": "zhsun",
        "operation": "signIn"
    }, {
        "date": "2022-08-08 00:15:20",
        "name": "zhsun",
        "operation": "signOut"
    }
]
console.log(
    Enumerable.from(data)
        .groupBy(obj => obj.name)
        .select(igp => ({ name: igp.key(), count: igp.count() }))
        .toArray()
)
//注意,不同于c#的是,如果keySelector是一个object,需要自己去实现compareSelector
console.log(
    Enumerable.from(data)
        .groupBy(obj => ({ date: obj.date, name: obj.name }),                                    //key Selector 
            obj => obj.operation,                                                                //element Selector 
            (key, operations) => ({ name: key.name, date: key.date, count: operations.count() }),//result Selector  
            key => JSON.stringify(key)                                                           //compare Selector 
        )
        .toArray()
)
//output
//[ { name: 'zhsun', count: 2 } ]
//[ { name: 'zhsun', date: '2022-08-08 00:15:20', count: 2 } ]
//连接
let data1 = [{
    "date": "2022-08-08 00:15:20",
    "name": "zhsun",
    "roleId": 2
}, {
    "date": "2022-08-08 00:15:20",
    "name": "fqh",
    "roleId": 1
}, {
    "date": "2022-08-08 00:15:20",
    "name": "pp",
    "roleId": 3
},]
let data2 = [{
    "roleId": 1,
    "role": "admin"
}, {
    "roleId": 2,
    "role": "user"
}]
console.log(
    Enumerable.from(data1)
        .join(data2,
            obj1 => obj1.roleId,
            obj2 => obj2.roleId,
            (obj1, obj2) => ({
                date: obj1.date,
                name: obj1.name,
                role: obj2.role
            })
        )
        .toArray()
)
//output
//[
//  { date: '2022-08-08 00:15:20', name: 'zhsun', role: 'user' },
//  { date: '2022-08-08 00:15:20', name: 'fqh', role: 'admin' }  
//]

大部分c# linq的方法都有实现,使用方式也大致相仿,可以从MSDN-Enumerable.Aggregate 方法开始阅读了解

项目中的使用

目前为止,我主要用在了以下两个方面

  • 前端数据可视化时可能需要进行复杂数据转换,如用户以不同的key去groupBy绘制图表
  • 写node脚本时简化数据转换的操作

其他

如果觉得这个库太小众,可以考虑lodash