Skip to content

Commit 8e10639

Browse files
committed
Fixing group by problem
1 parent a9f0583 commit 8e10639

File tree

4 files changed

+46
-37
lines changed

4 files changed

+46
-37
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "fromit",
33
"private": false,
4-
"version": "2.2.10",
4+
"version": "2.2.11",
55
"description": "Typescript linq",
66
"main": "dist/index.js",
77
"module": "dist/fromit.mjs",

src/async.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
type Selector<T, M = any> = (item: T, index: number) => PromiseLike<M> | M;
3-
type Matcher<T> = (item: T) => PromiseLike<boolean> | boolean
3+
type Matcher<T> = (item: T, index: number) => PromiseLike<boolean> | boolean
44
type Property<T> = keyof T;
55
const truthy: Matcher<any> = x => !!x;
66
type FlatElement<Arr, Depth extends number> = {
@@ -136,15 +136,17 @@ export abstract class AEnumerable<T> implements AsyncIterable<T> {
136136
}
137137

138138
async find(filter: Matcher<T>) {
139+
let index = 0;
139140
for await (let item of this) {
140-
if (filter(item)) return item;
141+
if (filter(item, index++)) return item;
141142
}
142143
return undefined;
143144
}
144145

145146
async some(filter: Matcher<T>) {
147+
let index = 0;
146148
for await (let item of this) {
147-
if (filter(item)) return true;
149+
if (filter(item, index++)) return true;
148150
}
149151
return false;
150152
}
@@ -463,9 +465,11 @@ class Skip<T> extends AEnumerable<T> {
463465
}
464466
} else {
465467
let skip = true;
468+
let index = -1;
466469
for await (let item of this.list) {
470+
index++;
467471
if (skip) {
468-
skip = await this._matcher(item);
472+
skip = await this._matcher(item, index);
469473
}
470474
if (!skip) {
471475
yield item;
@@ -488,8 +492,10 @@ class Take<T> extends Skip<T> {
488492
}
489493
}
490494
} else {
495+
let index = -1;
491496
for await (let item of this.list) {
492-
if (!(await this._matcher(item))) {
497+
index++;
498+
if (!(await this._matcher(item, index))) {
493499
return;
494500
}
495501
yield item;
@@ -505,8 +511,9 @@ class Filter<T> extends AEnumerable<T> {
505511
}
506512

507513
async *[Symbol.asyncIterator]() {
514+
let index = 0;
508515
for await (let item of this.list) {
509-
if (this.selector(item)) {
516+
if (this.selector(item, index++)) {
510517
yield item;
511518
}
512519
}

src/index.spec.ts

+6
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ test("skip", async () => {
112112
expect(from(a).take(2).last()).toBe(2);
113113
});
114114

115+
test("reverse group", async () => {
116+
const a = [3, 4, 1, 2, 5];
117+
expect(from(a).sort().reverse().take(2).reverse().toArray()).toStrictEqual([4, 5]);
118+
expect(from(a).sort().reverse().take(2).groupBy(x => x).map(x=> x.key).toArray()).toStrictEqual([5, 4]);
119+
});
120+
115121
test("take", async () => {
116122
let flag = false;
117123
function* gen() {

src/index.ts

+26-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {AEnumerable, AFrom} from './async';
22

33
type Selector<T, M = any> = (value: T, index: number) => M;
4-
type Matcher<T> = (item: T) => boolean;
4+
type Matcher<T> = (item: T, index: number) => boolean;
55
type Property<T> = keyof T;
66
const identity: Matcher<any> = x => !!x;
77
type FlatElement<Arr, Depth extends number> = {
@@ -117,15 +117,17 @@ abstract class Enumerable<T> implements Iterable<T> {
117117
}
118118

119119
find(filter: Matcher<T>) {
120+
let index = 0;
120121
for (let item of this) {
121-
if (filter(item)) return item;
122+
if (filter(item, index++)) return item;
122123
}
123124
return undefined;
124125
}
125126

126127
some(filter: Matcher<T>) {
128+
let index = 0;
127129
for (let item of this) {
128-
if (filter(item)) return true;
130+
if (filter(item, index++)) return true;
129131
}
130132
return false;
131133
}
@@ -280,7 +282,7 @@ abstract class Enumerable<T> implements Iterable<T> {
280282
}
281283

282284
class Group<V, K> extends Enumerable<V> {
283-
constructor(public key: K, private buffer: V[]) {
285+
constructor(public key: K, private buffer: Enumerable<V>) {
284286
super();
285287
}
286288

@@ -323,29 +325,18 @@ class GroupedEnumerable<V, K> extends Enumerable<Group<V, K>> {
323325
}
324326

325327
*[Symbol.iterator](): IterableIterator<Group<V, K>> {
326-
let last: K = null;
327-
let start = true;
328-
let buffer: V[] = [];
329-
let index = 0;
330-
for (let item of this.list.orderBy(this.selector)) {
331-
if (start) {
332-
start = false;
333-
last = this.selector(item, index++);
334-
buffer.push(item);
335-
continue;
336-
}
337-
let current = this.selector(item, index++);
338-
if (current !== last) {
339-
yield new Group<V, K>(last, buffer);
340-
buffer = [item];
341-
last = current;
342-
continue;
343-
}
344-
buffer.push(item);
345-
}
346-
if (buffer.length) {
347-
yield new Group<V, K>(last, buffer);
348-
}
328+
const seen = new Set<K>;
329+
let index = -1;
330+
for(const item of this.list) {
331+
index++;
332+
const key = this.selector(item, index);
333+
if (seen.has(key)) continue;
334+
seen.add(key);
335+
yield new Group(key,
336+
from(this.list).skip(index)
337+
.filter((item, sub) => this.selector(item, index + sub) === key)
338+
);
339+
}
349340
}
350341
}
351342

@@ -429,9 +420,11 @@ class Skip<T> extends Enumerable<T> {
429420
}
430421
} else {
431422
let skip = true;
423+
let index = -1;
432424
for (let item of this.list) {
425+
index++;
433426
if (skip) {
434-
skip = this._matcher(item);
427+
skip = this._matcher(item, index);
435428
}
436429
if (!skip) {
437430
yield item;
@@ -454,8 +447,10 @@ class Take<T> extends Skip<T> {
454447
}
455448
}
456449
} else {
450+
let index = -1;
457451
for (let item of this.list) {
458-
if (!this._matcher(item)) {
452+
index++;
453+
if (!this._matcher(item, index)) {
459454
return;
460455
}
461456
yield item;
@@ -488,8 +483,9 @@ class Filter<T> extends Enumerable<T> {
488483
}
489484

490485
*[Symbol.iterator]() {
486+
let index = 0;
491487
for (let item of this.list) {
492-
if (this.selector(item)) {
488+
if (this.selector(item, index++)) {
493489
yield item;
494490
}
495491
}

0 commit comments

Comments
 (0)