linqjs记录

linqjs记录

在LINQ.js中,你可以使用一系列方法来操作数组。以下是一些常见的LINQ.js数组方法:

教程:https://medium.com/swlh/data-manipulation-in-javascript-using-linq-f3759e00aceb

1.Enumerable.From(array):将普通数组转换为可查询的LINQ.js数组对象。
2.Where(predicate):根据指定的条件选择数组中的元素。

∗ ∗ w h e r e ( p r e d i c a t e : ( e l e m e n t : T , i n d e x : n u m b e r ) = > b o o l e a n ) : I E n u m e r a b l e < T > ; ∗ ∗ **where(predicate: (element: T, index: number) => boolean): IEnumerable<T>;** where(predicate:(element:T,index:number)=>boolean):IEnumerable<T>;

var filteredArray = Enumerable.From(array).Where((x)=> x > 5).ToArray();
3.Select(selector):对数组中的每个元素应用指定的转换函数,返回一个新的数组。
  1. 以下每个元素都乘以2
var transformedArray = Enumerable.From(array).Select((x)=> x * 2).ToArray();
var result = Enumerable.from(array).select((user, index) => ({...user,id: index + 1})).toArray();
A… select和where的区别如下:
在linq.js中,select和where是用于查询和筛选数据的两个关键字。它们的区别如下:1. Select:Select用于选择查询结果中的特定字段。它类似于SQL中的SELECT子句。使用Select关键字,你可以指定要从查询结果中返回的字段,并对这些字段进行转换或操作。例如,你可以使用Select来选择一个对象的某个属性,或者对查询结果进行计算或转换。2. Where:Where用于根据条件筛选出符合条件的数据。它类似于SQL中的WHERE子句。使用Where关键字,你可以指定一个条件表达式,用来过滤查询结果中的数据。只有满足条件的数据才会被包含在结果中。简而言之,Select用于选择特定字段并对其进行转换或操作,而Where用于筛选符合特定条件的数据。下面是一个示例,演示如何在linq.js中使用Select和Where:假设有一个包含学生信息的数组students,每个学生对象都有name和age两个属性。现在我们想选择年龄大于18岁的学生的姓名,可以使用以下代码:var students = [{ name: 'Alice', age: 19 },{ name: 'Bob', age: 17 },{ name: 'Charlie', age: 20 },{ name: 'David', age: 18 }
];var result = Enumerable.From(students).Where(function(student) {return student.age > 18;}).Select(function(student) {return student.name;}).ToArray();console.log(result); // 输出: ["Alice", "Charlie"]
在上面的代码中,Where函数用于筛选出年龄大于18岁的学生,而Select函数用于选择学生的姓名。最后,ToArray函数将结果转换为一个数组,方便输出或进一步操作。希望这个解释对你有帮助!如果有任何问题,请随时提问。
4.OrderBy(keySelector):按照指定的键选择器对数组进行升序排序。
var sortedArray = Enumerable.From(array).OrderBy(function(x) {return x;
}).ToArray();
5.OrderByDescending(keySelector):按照指定的键选择器对数组进行降序排序。
var sortedArray = Enumerable.From(array).OrderByDescending(function(x) {return x;
}).ToArray();
6.Reverse():反转数组中的元素顺序。
var reversedArray = Enumerable.From(array).Reverse().ToArray();
7.Skip(count):跳过数组中的前几个元素。
var skippedArray = Enumerable.From(array).Skip(2).ToArray();
8.Take(count):选择数组中的前几个或者前几条元素。
var takenArray = Enumerable.From(array).Take(3).ToArray();
9.groupBy:指定的键进行分组。

公式

groupBy<TKey, TElement, TResult, TCompare>(keySelector: (element: T) => TKey, elementSelector: (element: T) => TElement, resultSelector: (key: TKey, element: IEnumerable<TElement>) => TResult, compareSelector: (element: TKey) => TCompare): IEnumerable<TResult>;
let arr = [{ id: 1, name: '' }, { id: 2, name: '测试2' }, { id: 3, name: '测试3' }, { id: 4, name: '测试4' }]const cdrev = Enumerable.from(arr).where((c) =>c.name).groupBy((pet) => pet.id,(pet) => pet,(key, group) => ({key: key,receiveact: group.sum((p) => p.id),})).toArray();

下面逐步解释代码的作用:

  1. 创建一个包含对象的数组arr

    let arr = [{ id: 1, name: '' }, { id: 2, name: '测试2' }, { id: 3, name: '测试3' }, { id: 4, name: '测试4' }]
    
  2. 使用Enumerable.from方法将数组转换为可查询的对象:

    const cdrev = Enumerable.from(arr)
    
  3. 使用where方法进行筛选,只包含name属性不为空的对象:

    .where((c) => c.name)
    
  4. 使用groupBy方法按指定的键进行分组。这里使用id作为键:

    .groupBy((pet) => pet.id,(pet) => pet,(key, group) => ({key: key,receiveact: group.sum((p) => p.id),})
    )
    
    • 第一个参数 (pet) => pet.id 是分组的键,表示按照对象的id属性进行分组。
    • 第二个参数 (pet) => pet 是一个转换函数,它定义了每个分组中的元素应该是什么。
    • 第三个参数 (key, group) => ({ key: key, receiveact: group.sum((p) => p.id) }) 是一个聚合函数,它定义了如何聚合每个分组的结果。在这里,我们将分组的键作为key属性,然后计算每个分组中所有元素的id属性的和作为receiveact属性。
  5. 最后,使用toArray方法将分组的结果转换为数组:

    .toArray();
    

总结起来,给定一个包含对象的数组,该代码会筛选出name属性不为空的对象,并根据id属性对它们进行分组。然后,对每个分组中的元素进行聚合,生成一个包含keyreceiveact属性的对象数组。希望这样的解释对你有帮助!

10.过滤和筛选数据

使用 linq.js,你可以使用 Enumerable.from() 方法将数组转换为可查询的对象,然后使用链式调用来过滤和筛选数据。

首先,你需要引入 linq.js 库。然后,你可以使用以下代码来重写你的循环:

	// const iftypetwolist = [];// for (let i = 0; i < list.length; i++) {// 	const it = list[i];// 	if (it.children && it.children.length == 0 && it.ftype == 2) {// 		iftypetwolist.push(it.taskmanagerid);// 		iftypetwolist.push(it.taskacterid);// 	}// }import * as Enumerable from 'linq';
const iftypetwolist = Enumerable.from(list).where(it => it.children && it.children.length === 0 && it.ftype === 2).selectMany(it => [it.taskmanagerid, it.taskacterid]).distinct().where(it => it !== 0 && it.toString() !== 'null').orderBy(it => it).toArray();

在上面的代码中,Enumerable.from(list)list 数组转换为可查询的对象。然后,使用 where() 方法来过滤数据,只保留满足条件的元素。接下来,使用 selectMany() 方法来选择并展开每个元素的 taskmanageridtaskacterid 属性,并将它们放入一个新的数组中。然后,使用 distinct() 方法来去重,保留唯一的元素。接着,使用 where() 方法来过滤掉值为 0 或字符串为 ‘null’ 的元素。最后,使用 orderBy() 方法来对数组进行排序,并使用 toArray() 方法将查询结果转换回数组形式。

现在,iftypeonelistiftypetwolist 数组将包含符合条件的元素,并且已经去重、过滤和排序,与你的原始循环的结果相同。

11.distinct() 方法来去重,

条目10有案例

12.groupBy分组

g r o u p B y < T K e y , T E l e m e n t , T R e s u l t , T C o m p a r e > ( k e y S e l e c t o r : ( e l e m e n t : T ) = > T K e y , e l e m e n t S e l e c t o r : ( e l e m e n t : T ) = > T E l e m e n t , r e s u l t S e l e c t o r : ( k e y : T K e y , e l e m e n t : I E n u m e r a b l e < T E l e m e n t > ) = > T R e s u l t , c o m p a r e S e l e c t o r : ( e l e m e n t : T K e y ) = > T C o m p a r e ) : I E n u m e r a b l e < T R e s u l t > ; groupBy<TKey, TElement, TResult, TCompare>( keySelector: (element: T) => TKey, elementSelector: (element: T) => TElement, resultSelector: (key: TKey, element: IEnumerable<TElement>) => TResult, compareSelector: (element: TKey) => TCompare): IEnumerable<TResult>; groupBy<TKey,TElement,TResult,TCompare>(keySelector:(element:T)=>TKey,elementSelector:(element:T)=>TElement,resultSelector:(key:TKey,element:IEnumerable<TElement>)=>TResult,compareSelector:(element:TKey)=>TCompare):IEnumerable<TResult>;

单字段分组
var array = [{id: 1, name: 'Order 1', product: 'Ford'},{id: 1, name: 'Order 1', product: 'BMW'},{id: 2, name: 'Order 2', product: 'Toyota'},{id: 2, name: 'Order 2', product: 'Skoda'},{id: 2, name: 'Order 2', product: 'Fiat'}
];
var result = Enumerable.from(array).groupBy(g => g.name,element => element,(key, items) => ({key, items: items.toArray()})).toArray()
多字段分组
.groupBy(g => ({ g.name, g.id })),element => element,(key, items) => ({key, items: items.toArray()})).toArray();

这段代码是使用Vue.js中的groupBy函数对一个数组进行分组操作。

  1. groupBy函数接受三个参数:一个用于分组的键函数、一个用于选择分组元素的函数和一个用于处理每个分组的函数。

  2. 第一个参数(pet) => pet.id是一个箭头函数,它定义了如何从数组中的每个元素中提取一个键。在这个例子中,我们使用pet.id作为键来分组。

  3. 第二个参数(pet) => pet是一个箭头函数,它定义了如何选择分组元素。在这个例子中,我们选择了整个pet对象作为分组元素。

  4. 第三个参数(key, group) => ({ key: key, receiveact: group.sum((p) => p.id) })是一个箭头函数,它定义了如何处理每个分组。在这个例子中,我们创建了一个新的对象,其中包含两个属性:keyreceiveact

  5. key属性是分组的键,它的值是第一个参数(pet) => pet.id提取的键。

  6. receiveact属性是对每个分组中的元素进行求和操作的结果。在这个例子中,我们使用了group.sum((p) => p.id)来计算每个分组中pet.id的总和。

总结一下,这段代码的作用是将一个数组按照pet.id进行分组,并计算每个分组中pet.id的总和。最终返回一个包含分组键和总和的对象数组。

let arr = [{ id: 1, name: '测试1' },{ id: 2, name: '测试2' },{ id: 3, name: '测试3' },{ id: 4, name: '测试4' },];const cdrev = Enumerable.from(arr).where((c) => {if (c.name) {return c;}}).groupBy((pet) => pet.name,//选择以哪个键分组(pet) => pet,(key, group) => ({key: key,//此时的key等于 pet.namereceiveact: group.sum((p) => p.id),})).toArray();
//以下代码自动返回对象
.groupBy((pet) => pet.billid,(pet) => pet,(key, group) => ({key: key,fname: '',billno: '',pid: 0,fcount: group.count(),plantotal: ~~group.sum((p) => p.plantotal),plantotalaftertax: ~~group.sum((p) => p.plantotalaftertax),invoicetotal: ~~group.sum((p) => p.invoicetotal),invoicetotalaftertax: ~~group.sum((p) => p.invoicetotalaftertax),receiveact: 0,receiveactaftertax: 0,percent: 0,}))
//第二种请概况,也可以只构建分组let result = Enumerable.from(arr).groupBy((item: any) => item.bigarea).select((group) => ({bigarea: group.key,questionid: id,childern: group.groupBy((item: any) => item.city).select((cityGroup: any) => ({city: cityGroup.key,childern: cityGroup.groupBy((it: any) => it.brand).select((ftypeGroup: any) => ({brand: ftypeGroup.key,plannedNum: ftypeGroup.count(),childern: ftypeGroup.toArray(),})).toArray(),})).toArray(),})).toArray();const allQuestionnaireUserList = Enumerable.from(allQuestionnaireUser).groupBy((item: any) => item.questionid).toObject((group) => group.key,(group) => group.toArray());
//分组后设置,属性名// [// 	{ ftype: 1, name: '1111' },// 	{ ftype: 1, name: '2222' },// 	{ ftype: 2, name: '333333' },// ];
let groupedByFtype = Enumerable.from(rawData.value).groupBy((x: any) => x.ftype).select((g: any) => ({ftype: g.key,children: g.toArray(),})).toArray();
//原来数组
const originalArray = [{ id: 1, name: '222' },{ id: 2, name: '3333' },{ id: 1, name: 333 },
];
//结果对象{1: [{ id: 1, name: '222' },{ id: 1, name: 333 }],2: [{ id: 2, name: '3333' }],}const allQuestionnaireUserList = Enumerable.from(allQuestionnaireUser).groupBy((item: any) => item.id).toObject((group) => group.key,(group) => group.toArray());
13.将for循环改为linq写法
	let ftypeArr = [];for (let i = 0; i < groupedByFtype.length; i++) {const el = groupedByFtype[i];let obj = { label: '', value: i + 1 };obj.label = el.ftype;ftypeArr.push(obj);}let ftypeArr = Enumerable.range(0, groupedByFtype.length).select((i) => {let el = groupedByFtype[i];return { label: el.ftype, value: i + 1 };}).toArray();使用LINQ.js实现上述代码可以按照以下步骤进行:1. 首先,确保已经引入了LINQ.js库。2. 使用LINQ.js的`Enumerable.Range`方法创建一个从0`groupedByFtype.length - 1`的整数序列。3. 使用`Enumerable.Select`方法对整数序列进行映射,将每个整数`i`转换为一个包含`label``value`属性的对象。4. 在映射函数中,设置`label`属性为`groupedByFtype[i].ftype`,设置`value`属性为`i + 1`5. 使用`Enumerable.ToArray`方法将LINQ查询结果转换为数组。下面是使用LINQ.js实现的代码:```javascript
let ftypeArr = Enumerable.Range(0, groupedByFtype.length).Select(i => {let el = groupedByFtype[i];return { label: el.ftype, value: i + 1 };}).ToArray();
```这样,你就可以使用LINQ.js来实现相同的功能了。
13.0 selectMany:将属性展开为一个扁平的数组(将一个属性对应的值(数组)直接变成循环的数组)
	// let arr = [];// for (let i = 0; i < typePullDownList.value.length; i++) {// 	const el = typePullDownList.value[i];// 	if (el.value == e) {// 		arr = el.children;// 		break;// 	}// }// let cityArr = Enumerable.from(arr)// 	.groupBy((x: any) => x.city)// 	.select((g: any) => ({// 		city: g.key || '未设置城市',// 		children: g.toArray(),// 	}))// 	.select((el, i) => ({// 		label: el.city,// 		value: i + 1,// 		children: el.children,// 	}))// 	.toArray();let cityArr = Enumerable.from(typePullDownList.value).where((el) => el.value == e).selectMany((el) => el.children).groupBy((x: any) => x.city).select((g: any) => ({city: g.key || '未设置城市',children: g.toArray(),})).select((el, i) => ({label: el.city,value: i + 1,children: el.children,})).toArray();解释:	在这个合并后的代码中,我们首先使用`where`方法筛选出`typePullDownList.value``value`属性等于`e`的元素。然后,我们使用`selectMany`方法将这些元素的`children`属性展开为一个扁平的数组。接下来,我们使用`groupBy`将数组按照`city`属性进行分组。然后,我们使用`select`将每个分组转换为一个对象,其中包含`city``children`属性。接着,我们使用`select`将每个对象转换为一个新的对象,其中包含`label``value``children`属性。最后,我们使用`toArray`将结果转换为一个数组。请注意,我们还添加了一个条件来检查`city`属性是否存在,如果不存在,则将其设置为'未设置城市'。这样可以确保在没有城市属性的情况下,仍然可以正确地生成结果数组。
13.1:常用for循环(firstOrDefault)
let name;
for (let i = 0; i < typePullDownList.value.length; i++) {const element = typePullDownList.value[i];if (element.value == typePullDownId.value) {name = element.label;break}
}使用LINQ.js可以将上述代码转换为以下形式:```javascript
let name = Enumerable.From(typePullDownList.value).Where(element => element.value == typePullDownId.value).Select(element => element.label).FirstOrDefault();
```这里的`Enumerable.From`方法将数组`typePullDownList.value`转换为一个可查询的集合。然后使用`Where`方法筛选出`value`属性等于`typePullDownId.value`的元素。接着使用`Select`方法选择`label`属性,并最后使用`FirstOrDefault`方法获取第一个匹配的元素的`label`属性值。请确保在使用LINQ.js之前先引入该库。
14.去重(.distinct())
	itemsmineidarr.value = Enumerable.from(datamod).select('tid') // 选择'tid'属性.distinct() // 去重.toArray(); // 转换为数组
15.first (返回集合的第一个元素。如果集合中不存在任何元素,则应用程序将抛出异常。如果集合为空,则返回默认值。)
var array = [
{name: 'ondrej', lastname: 'hlouzek', age: 38},
{name: 'jakub', lastname: 'hlouzek', age: 39}
];var result = Enumerable.from(array).orderBy(o => o.name).first();
16.last (返回集合的最后一个元素。如果集合中不存在任何元素,则应用程序将抛出异常。如果集合为空,LastorDefault返回默认值。)
var array = [
{name: 'ondrej', lastname: 'hlouzek', age: 38},
{name: 'jakub', lastname: 'hlouzek', age: 39}
];var result = Enumerable.from(array).orderBy(o => o.name).last();
17.single (只有当应用该方法的集合只有一个元素时,该方法才返回一个对象。在singleOrDefault的情况下,只有当它所应用的集合返回单个元素或空集合时,它才返回一个对象。如果集合包含2个或更多元素,则。抛出异常。)
var array = [
{name: 'ondrej', lastname: 'hlouzek', age: 38}
];
var result = Enumerable.from(array).single();
18.take(此方法返回指定数量的记录。它通常被用来与orderBy方法一起。)
var array = [{name: 'Order 1', cost: 15233},{name: 'Order 2', cost: 33533},{name: 'Order 3', cost: 23511},{name: 'Order 4', cost: 11244},{name: 'Order 5', cost: 44432}
];
var result = Enumerable.from(array).orderBy(o => o.cost).take(2).toArray();
19.contains 类似includes (配合where,条件是contains方法。您可以使用此函数搜索特定的值列表。在本例中,我要查找两个特定的文档号。)

c o n t a i n s ( v a l u e : T ) : b o o l e a n ; contains(value: T): boolean; contains(value:T):boolean;

//查找array中documentNumber在numbers中的数据var array = [{documentNumber: '140710', createdDate: '2019-11-01', contract: '', total: 242.64,	reference: 'PRIMARK MILAN RCW LAURENCE TAYLOR'},{documentNumber: '140352', createdDate: '2019-11-02', contract: 'PRI19/00050',	total: 22865.90, reference: '***GF WHC***'},{documentNumber: '140120', createdDate: '2019-11-02', contract: 'PRI19/00052',	total: 17732.70, reference: '***GF WHC***'},{documentNumber: '140117', createdDate: '2019-11-03', contract: 'PRI19/00011',	total: 15982.80, reference: '***GF WHC***'},{documentNumber: '139977', createdDate: '2019-11-04', contract: '', total:	7314.98,	reference: '***FIRST FLOOR RCW&PERIMETER***'},{documentNumber: '139976', createdDate: '2019-11-08', contract: 'PRI19/00028',	total: 10147.23, reference: ''},{documentNumber: '139971', createdDate: '2019-11-13', contract: '', total: 16285.72, reference: '***FIRST FLOOR CD ATRIUMS***'}, {documentNumber: '139968', createdDate: '2019-11-15', contract: '', total: 8111.79, reference: '***FIRST FLOOR B-FRAMES***'},{documentNumber: '139817', createdDate: '2019-11-18', contract: 'PRI19/00052', total: 5190.59, reference: '***GF RCW&RET***'},{documentNumber: '139617', createdDate: '2019-11-23', contract: 'PRI19/00052', total: 14378.54, reference: '*****GROUND FLOOR CD*****'}];var numbers = ['139976', '139971'];
var result = Enumerable.from(array)
.where(w => Enumerable.from(numbers).contains(w.documentNumber))
.toArray();
//结果:[ {documentNumber: '139976', createdDate: '2019-11-08', contract: 'PRI19/00028',	total: 10147.23, reference: ''},//{documentNumber: '139971', createdDate: '2019-11-13', contract: '', total: 16285.72, reference: '***FIRST FLOOR CD //ATRIUMS***'}] 
20.all (只有当所有元素都满足指定的条件时,all方法才返回true)

a l l ( p r e d i c a t e : ( e l e m e n t : T ) = > b o o l e a n ) : b o o l e a n ; all(predicate: (element: T) => boolean): boolean; all(predicate:(element:T)=>boolean):boolean;

var array = [1, 2, 3, 4, 5];var allGreaterThanZero = Enumerable.from(array).all(element => element > 0);console.log(allGreaterThanZero); // 输出 true
21.any (any方法只有在没有元素满足谓词中指定的条件时才返回数据。)
22.GroupJoin(基于键相等关系将两个序列的元素关联起来,并将结果分组。)

g r o u p J o i n < T I n n e r , T K e y , T R e s u l t > ( i n n e r : I E n u m e r a b l e < T I n n e r > , o u t e r K e y S e l e c t o r : ( o u t e r : T ) = > T K e y , i n n e r K e y S e l e c t o r : ( i n n e r : T I n n e r ) = > T K e y , r e s u l t S e l e c t o r : ( o u t e r : T , i n n e r : I E n u m e r a b l e < T I n n e r > ) = > T R e s u l t , c o m p a r e S e l e c t o r ? : ( o b j : T ) = > T K e y ) : I E n u m e r a b l e < T R e s u l t > ; groupJoin<TInner, TKey, TResult>(inner: IEnumerable<TInner>, outerKeySelector: (outer: T) => TKey, innerKeySelector: (inner: TInner) => TKey, resultSelector: (outer: T, inner: IEnumerable<TInner>) => TResult, compareSelector?: (obj: T) => TKey): IEnumerable<TResult>; groupJoin<TInner,TKey,TResult>(inner:IEnumerable<TInner>,outerKeySelector:(outer:T)=>TKey,innerKeySelector:(inner:TInner)=>TKey,resultSelector:(outer:T,inner:IEnumerable<TInner>)=>TResult,compareSelector?:(obj:T)=>TKey):IEnumerable<TResult>;

var orders = [{id: 1, name: 'Order 1'}
];
var orderItems = [{ orderId: 1, product: 'Ford' },{ orderId: 1, product: 'BMW' }
]
var result = Enumerable.from(orders).groupJoin(Enumerable.from(orderItems),pk => pk.id,fk => fk.orderId,(order, items) => ({...order, items: items.toArray()})).toArray();
23.聚合函数(Aggregation functions)
min(selector?: (element: T) => number): number;
max(selector?: (element: T) => number): number;
average(selector?: (element: T) => number): number;    
count(predicate?: (element: T, index: number) => boolean): number;
sum(selector?: (element: T) => number): number;
可以将以下类型的aggfunc (selector ?: (element: T) => number): number聚合函数应用于IEnumerable<T>集合:
min-返回集合中的最小值
Max -返回集合中的最大值
average-返回集合中的平均值
Count -返回集合中元素的个数
Sum -返回集合中元素的和
var orderItems = [{ orderId: 1, product: 'Ford', cost: 10000 },{ orderId: 1, product: 'BMW', cost: 30000 },{ orderId: 2, product: 'Toyota', cost: 20000 }, { orderId: 2, product: 'Skoda', cost: 8000 },{ orderId: 2, product: 'Fiat', cost: 6000 }
]
var result = Enumerable.from(orderItems).groupBy(g => g.orderId).select(s => ({orderId: s.key(),max: s.max(m => m.cost),min: s.min(m => m.cost),avg: s.average(m => m.cost),  count: s.count(),sum: s.sum(s => s.cost)
})).toArray();

效果图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

24.MaxBy, MinBy(返回数组中,根据某个属性判断返回某行元素)

c o n s t r e s u l t = E n u m e r a b l e . f r o m ( o r d e r s ) . m a x B y ( s = > s . t o t a l ) ; const result = Enumerable.from(orders) .maxBy(s => s.total); constresult=Enumerable.from(orders).maxBy(s=>s.total);

查询查找列(红色列)中的最大值,并返回整个行(黄色行)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

25.Zip用于连接两个集合
zip<U, TResult>(second: IEnumerable<U>, resultSelector: (first: T, second: U, index: number) => TResult): IEnumerable<TResult>
export const orders = [{ id: 1, name: 'Order 1', createdDate: '2020.8.1' },{ id: 2, name: 'Order 2', createdDate: '2020.8.2' },{ id: 3, name: 'Order 3', createdDate: '2020.8.5' },{ id: 3, name: 'Order 3', createdDate: '2020.8.5' },];export const orderItems = [{ row: 1, cost: 20000 },{ row: 2, cost: 30000 },{ row: 3, cost: 40000 },{ row: 4, cost: 50000 },]const result = Enumerable.from(orders).zip(orderItems, (left, right) => ({ ...left, ...right })).toArray();
26.forEach
Enumerable.from(array).forEach(f => console.log(`item ${f}`);
27.多字段排序

排序命令如下:

orderBy—第一个按升序排序的命令

orderbydescent—第一个按降序排序的命令

thenBy—下一个按升序排序的命令

thenbydescent—下一个按降序排序的命令

Enumerable.from(array).orderByDescending(o => o.lastname).thenBy(o => o.name).thenByDescending(o => o.age)
28.Inner Join 求两个集合的交集(1:1,1:N,…)

公式

join<TInner, TKey, TResult>(inner: IEnumerable<TInner>, outerKeySelector: (outer: T) => TKey, innerKeySelector: (inner: TInner) => TKey, resultSelector: (outer: T, inner: TInner) => TResult, compareSelector?: (obj: T) => TKey): IEnumerable<TResult>;

只有当记录存在于两端(集合、表)时,内部连接才返回数据。如果其中一侧或另一侧的记录缺失,则该记录将不会被返回。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

.join命令用于实现内部连接。左右集合(表)的连接是使用主键和外键来解决的。只要在左侧和右侧找到匹配,就返回连接的记录。根据图片。左边是主键Id= 1,右边是外键OrderId = 1 pk 1 = fk 1。在这种情况下,返回两行,其中左侧根据右侧的行重复。这是一个类型1:N连接。

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

29.Left Join

左外连接是返回第一个集合的每个元素的连接,而不管它在第二个集合中是否有任何相关元素。您可以使用LINQ通过对组连接的结果调用DefaultIfEmpty方法来执行左外连接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在实践中,最常见的情况是连接两个数据源。这是一个连接,只有在主键和外键之间存在连接时,辅助资源才会连接到主资源。主要来源保持不变

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

const result = Enumerable.from(orders).groupJoin(Enumerable.from(orderItems),pk => pk.id,fk => fk.orderId,(left, right) => ({...left, right})).selectMany(m => m.right.defaultIfEmpty(),(left, right) => ({...left, ...right})).toArray();

结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以封装成函数

export const LeftJoin = (source, inner, pk, fk, result) => Enumerable.from(source).groupJoin(Enumerable.from(inner),s => pk(s),i => fk(i),(left, right) => ({left, right})).selectMany(m => m.right.defaultIfEmpty(),(prev, right) => result(prev.left, right));
30.Right join 右外连接

右外连接是第二个集合的每个元素所在的连接返回,不管它在第一个元素中是否有任何相关元素收集。方法来执行右外连接在组连接的结果上使用DefaultIfEmpty方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

右连接与左连接完全相反。这是一个连接,只有当主键和外键之间存在链接时,主资源才会连接到辅助资源。二次源保持不变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

与leftJoin的情况一样,LINQ中没有rightJoin函数,因此我们将使用LINQ自己编写它。

Enumerable.prototype.rightJoin = function(inner, pk, fk, result) {return RightJoin(this, inner, pk, fk, result);
}

结果如下

const result = Enumerable.from(orders).rightJoin(Enumerable.from(orderItems),pk => pk.id,fk => fk.orderId,(left, right) => ({...left, ...right})
).toArray();

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

31.Full outer join 合并两个表

当左表 (table1) 或右表 (table2) 记录中有匹配项时,FULL OUTER JOIN 关键字将返回所有记录。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它基本上同时执行左连接和右连接。因此,将显示来自左集合和右集合的所有记录。同样,在LINQ中没有调用完全外部连接的等效组件,因此我们编写自己的组件。正如您将看到的,完整的外部连接将是我们已经创建的LeftJoin和RightJoin方法的组合。

export const FullOuterJoin = (source, inner, pk, fk, result) => {var left = LeftJoin(source, inner, pk, fk, result);var right = RightJoin(source, inner, pk, fk, result);return left.unionDistinct(right);
}

我们将用fulllouterjoin方法扩展Enumerable

Enumerable.prototype.fullOuterJoin = function(inner, pk, fk, result) {return FullOuterJoin(this, inner, pk, fk, result);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

即使左侧的记录Id = 3在右侧没有相应的记录,右侧的记录Userld = 4在左侧没有相应的记录,它们仍然会在结果集合中。结果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/154953.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GLTF纹理贴图工具让模型更逼真

1、如何制作逼真的三维模型&#xff1f; 要使三维模型看起来更加逼真&#xff0c;可以考虑以下几个方面&#xff1a; 高质量纹理&#xff1a;使用高分辨率的纹理贴图可以增强模型的细节和真实感。选择适合模型的高质量纹理图像&#xff0c;并确保纹理映射到模型上的UV坐标正确…

多媒体播放软件 Infuse mac中文特点介绍

Infuse mac是一款多媒体播放器应用&#xff0c;它支持播放多种格式的视频文件、音频文件和图片文件&#xff0c;并且可以通过AIrPlay将媒体内容投放到其他设备上。Infuse还支持在线视频流媒体播放和本地网络共享&#xff0c;用户可以通过它来访问家庭网络上的媒体文件。 Infuse…

猫头虎带您了解CSDN1024城市开发者大会分会场报名指南(文末送30元优惠券)

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

测试经理应该怎么写测试部门年终总结报告?

年终总结一般对季度、半年度或年度总结的一个整理&#xff0c;我们需要定期对工作中的内容进行定期总结和复盘。将每一次复盘中总结出来的一些收获叠加起来&#xff0c;在针对性地调整一下&#xff0c;就是一份合格的年终总结。具体可以分为如下几个步骤&#xff1a; 1.先把这…

c++视觉处理-----cv::findContours函数和图像进行去噪、平滑、边缘检测和轮廓检测,动态检测图形

cv::findContours cv::findContours 是OpenCV中用于查找图像中对象轮廓的函数。轮廓是对象的边界&#xff0c;通常用于对象检测、分割和形状分析。cv::findContours 函数的基本用法如下&#xff1a; cv::findContours(image, contours, hierarchy, mode, method, offset cv:…

【广州华锐互动】AR轨道交通综合教学平台的应用

轨道交通是一种复杂且精密的系统&#xff0c;涵盖了众多技术和工程学科&#xff0c;包括机械、电气和计算机科学等。对于学生来说&#xff0c;理解和掌握这些知识是一项挑战。然而&#xff0c;AR技术的出现为解决这一问题提供了可能。 通过AR技术&#xff0c;教师可以创建生动、…

国产化技术探究达梦8数据库搭建一主一从双机热备守护Data Watch集群搭建实战windows版本

国产化技术探究达梦8数据库搭建一主一从双机热备守护Data Watch集群搭建实战windows版本 如果是Linux版本达梦8部署则参考笔者另一篇博文 https://blog.csdn.net/nasen512/article/details/133737692此文章针对是windows版本的达梦部署 1、测试环境介绍 服务器类型IP地址操…

WorkPlus一站式解决方案,助力企业构建统一门户系统

在信息爆炸的时代&#xff0c;企业管理面临着海量的数据和各类业务应用的复杂性。如何实现信息的井然有序、高效管理&#xff0c;成为企业发展的关键。WorkPlus作为领先的品牌&#xff0c;致力于打造统一门户系统&#xff0c;为企业提供全方位的服务和解决方案。本文将以知乎的…

Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

Linux系统编程:编译过程以及GDB调试

编译工具链SDK&#xff08;Software Development Kit&#xff09; 在windows下编写程序&#xff0c;我们通常会用IDE&#xff0c;比如idea、vs等&#xff0c;这些工具将编译链接什么的全都暗地里解决好了我们只要写程序就行&#xff0c;但很明显&#xff0c;在Linux系统下做不…

前端axios发送请求,在请求头添加参数

1.在封装接口传参时&#xff0c;定义形参&#xff0c;params是正常传参&#xff0c;name则是我想要在请求头传参 export function getCurlList (params, name) {return request({url: ********,method: get,params,name}) } 2.接口调用 const res await getCurlList(params,…

ubuntu离线编译安装cmake 3.22.5(could not fonud OPENSSL) and cmake-versinon查不到版本问题

1、首先去cmake官网下载压缩包,例如: cmake-3.22.5.tar.gz 2、拉到ubuntu进行解压: tar -zxcf cmake-3.22.5.tar.gz 3、cd 进入目录 cd cmake-3.22.5 4、执行configure可执行文件 ./configure 如果在编译过程中出现报错:Could NOT findOpenSSL,原因可能是缺少ssl库 按…

从城市吉祥物进化到虚拟人IP需要哪些步骤?

在2023年成都全国科普日主场活动中&#xff0c;推出了全国首个科普数字形象大使“科普熊猫”&#xff0c;科普熊猫作为成都科普吉祥物&#xff0c;是如何进化为虚拟人IP&#xff0c;通过动作捕捉、AR等技术&#xff0c;活灵活现地出现在大众眼前的&#xff1f; 以广州虚拟动力虚…

【Acwing187】导弹防御系统(LIS+剪枝+贪心+dfs+迭代加深)

题目描述 看本文需要准备的知识 1.最长上升子序列&#xff08;lis&#xff09;的算法思想和算法模板 2.acwing1010拦截导弹&#xff08;lis贪心&#xff09;题解 本题题解&#xff0c;需要知道这种贪心算法 3.简单了解dfs暴力搜索、剪枝、搜索树等概念 思路讲解 dfs求最…

代数——第3章——向量空间

第三章 向量空间(Vector Spaces) fmmer mit den einfachsten Beispielen anfangen. (始终从最简单的例子开始。) ------------------------------David Hilbert 3.1 (R^n)的子空间 我们的向量空间的基础模型(本章主题)是n 维实向量空间 的子空间。我们将在本节讨论它。…

【Qt】顶层窗口和普通窗口区别以及用法

区别 在Qt项目开发中&#xff0c;经常会用到窗体控件用于显示及数据操作和其他交互等。 但&#xff0c;窗体分为顶层窗口&#xff08;Top-level Window&#xff09;和普通窗口&#xff08;Regular Window&#xff09;。 他们之间是有区别的&#xff0c;包括在项目实际中的用法…

实现动态表单的一种思路 | 京东云技术团队

一、动态表单是什么 区别于传统表单前后端配合联调的开发实现方式&#xff0c;动态表单通过一种基于元数据管理的配置化方法来实现表单的动态生成&#xff0c;并能根据配置自由增改删指定字段。实现特定需求的自助化。 图1.1 传统表单前后台协作模式 图1.2 动态表单前后台协作…

CY7C68013A芯片与FPGA

文章目录 环境软件环境其它工具 USB基础USB2.0设备组成USB设备模型USB设备分层USB Host Controller 主机控制器分类 USB HostUSB2.0 数据帧USB传输事务传输类型 芯片 cypress CY7C68013开发包安装FX3 固件程序设计步骤 驱动程序设计计算机上层应用软件USB2.0 FPGAUSB基础资料官…

单目标应用:墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、墨西哥蝾螈优化算法MAO 墨西哥蝾螈优化算法&#xff08;Mexican Axolotl Optimization&#xff0c;MAO&#xff09;由Yenny Villuendas-Rey 1等人于2021…

Clion中使用C/C++开发stm32程序

前言 从刚开始学习阶段&#xff0c;一直是用的keil5开发stm32程序&#xff0c;自从看到稚晖君推荐的CLion开发嵌入式程序后&#xff0c;这次尝试在CLion上开发stm32程序。 1、配置CLion用于STM32开发的环境 这里我就不详细写了&#xff0c;没必要重新写&#xff0c;网上教程很多…