Open 02020 opened 1 year ago
type Predicate<T> = (item: T) => boolean;
type Selector<T, U> = (item: T) => U;
type GroupKeySelector<T, K> = (item: T) => K;
type Collection<T> = {
filter(predicate: Predicate<T>): Collection<T>;
map<U>(selector: Selector<T, U>): Collection<U>;
groupBy<K>(keySelector: GroupKeySelector<T, K>): Map<K, T[]>;
toArray(): T[];
};
function from<T>(items: T[]): Collection<T> {
return {
filter(predicate: Predicate<T>): Collection<T> {
return from(items.filter(predicate));
},
map<U>(selector: Selector<T, U>): Collection<U> {
return from(items.map(selector));
},
groupBy<K>(keySelector: GroupKeySelector<T, K>): Map<K, T[]> {
const map = new Map<K, T[]>();
for (const item of items) {
const key = keySelector(item);
const group = map.get(key) ?? [];
group.push(item);
map.set(key, group);
}
return map;
},
toArray(): T[] {
return [...items];
},
};
}
interface Person {
name: string;
age: number;
}
const people: Person[] = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 35 },
];
const result = from(people)
.filter((person) => person.age > 25)
.groupBy((person) => Math.floor(person.age / 10) * 10)
.map(([ageGroup, people]) => ({
ageGroup,
totalAge: people.reduce((sum, person) => sum + person.age, 0),
count: people.length,
}))
.toArray();
console.log(result);
type Predicate<T> = (item: T) => boolean;
type Selector<T, U> = (item: T) => U;
type GroupKeySelector<T, K> = (item: T) => K;
interface Collection<T> {
filter(predicate: Predicate<T>): Collection<T>;
map<U>(selector: Selector<T, U>): Collection<U>;
toArray(): T[];
pluck<K extends keyof T>(keys: K[]): Collection<Pick<T, K>>;
}
function from<T>(items: T[]): Collection<T> {
return {
filter(predicate: Predicate<T>): Collection<T> {
return from(items.filter(predicate));
},
map<U>(selector: Selector<T, U>): Collection<U> {
return from(items.map((item) => selector(item)));
},
toArray(): T[] {
return items;
},
pluck<K extends keyof T>(keys: K[]): Collection<Pick<T, K>> {
return from(
items.map((item) =>
keys.reduce((obj, key) => {
obj[key] = item[key];
return obj;
}, {} as Pick<T, K>)
)
);
},
};
}
type Predicate<T> = (item: T) => boolean;
type Selector<T, U> = (item: T) => U;
type GroupKeySelector<T, K> = (item: T) => K;
type Collection<T> = {
filter(predicateFn: Predicate<T>): Collection<T>;
map<U>(selectorFn: Selector<T, U>): Collection<U>;
groupBy<K>(keySelectorFn: GroupKeySelector<T, K>): Map<K, T[]>;
toArray(): T[];
};
function createCollection<T>(itemsArray: T[]): Collection<T> {
return {
filter(predicateFn: Predicate<T>): Collection<T> {
return createCollection(itemsArray.filter(predicateFn));
},
map<U>(selectorFn: Selector<T, U>): Collection<U> {
return createCollection(itemsArray.map(selectorFn));
},
groupBy<K>(keySelectorFn: GroupKeySelector<T, K>): Map<K, T[]> {
const map = new Map<K, T[]>();
for (const item of itemsArray) {
const key = keySelectorFn(item);
const group = map.get(key) ?? [];
group.push(item);
map.set(key, group);
}
return map;
},
toArray(): T[] {
return [...itemsArray];
},
};
}
type Predicate<T> = (item: T) => boolean;
type Selector<T, U> = (item: T) => U;
type GroupKeySelector<T, K> = (item: T) => K;
type Collection<T> = {
filter: (predicateFn: Predicate<T>) => Collection<T>;
map: <U>(selectorFn: Selector<T, U>) => Collection<U>;
groupBy: <K>(keySelectorFn: GroupKeySelector<T, K>) => Map<K, T[]>;
toArray: () => T[];
};
const createCollection = <T>(itemsArray: T[]): Collection<T> => ({
filter: (predicateFn) =>
createCollection(itemsArray.filter(predicateFn)),
map: (selectorFn) => createCollection(itemsArray.map(selectorFn)),
groupBy: (keySelectorFn) => {
const map = new Map();
for (const item of itemsArray) {
const key = keySelectorFn(item);
const group = map.get(key) || [];
group.push(item);
map.set(key, group);
}
return map;
},
toArray: () => [...itemsArray],
});
type UnaryFn<T, R> = (x: T) => R;
function compose<T, R, U>(
f: UnaryFn<T, R>,
g: UnaryFn<R, U>
): UnaryFn<T, U> {
return (x: T) => g(f(x));
}
function pipe<T, R, U>(
f: UnaryFn<T, R>,
g: UnaryFn<R, U>
): UnaryFn<T, U> {
return (x: T) => f(g(x));
}
function add(x: number): UnaryFn<number, number> {
return (y: number) => x + y;
}
function subtract(x: number): UnaryFn<number, number> {
return (y: number) => x - y;
}
function multiply(x: number): UnaryFn<number, number> {
return (y: number) => x * y;
}
function divide(x: number): UnaryFn<number, number> {
return (y: number) => x / y;
}
const result = compose(
add(10),
divide(2),
subtract(3),
multiply(2)
)(5);
console.log(result); // Output: 9
class Calculator {
private readonly initial: number;
constructor(initial: number) {
this.initial = initial;
}
add(value: number): Calculator {
return new Calculator(this.initial + value);
}
subtract(value: number): Calculator {
return new Calculator(this.initial - value);
}
multiply(value: number): Calculator {
return new Calculator(this.initial * value);
}
divide(value: number): Calculator {
return new Calculator(this.initial / value);
}
getResult(): number {
return this.initial;
}
}
const result = new Calculator(10)
.add(5)
.multiply(2)
.subtract(3)
.divide(4)
.getResult();
console.log(result); // Output: 3.25
type PipeFunction<T, U> = (data: T[]) => U[];
function filter<T>(predicate: (item: T) => boolean): PipeFunction<T, T> {
return (data) => data.filter(predicate);
}
function map<T, U>(mapper: (item: T) => U): PipeFunction<T, U> {
return (data) => data.map(mapper);
}
function flatMap<T, U>(mapper: (item: T) => U[]): PipeFunction<T, U> {
return (data) => data.flatMap(mapper);
}
function pipe<T, U>(data: T[], ...fns: PipeFunction<any, any>[]): U[] {
return fns.reduce((result, fn) => fn(result), data);
}
// 使用示例
const data = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 40 },
];
const result = pipe(
data,
filter((item) => item.age >= 30),
map((item) => item.name)
);
console.log(result); // ['Bob', 'Charlie']
class Pipeline<T> {
private readonly data: T[];
constructor(data: T[]) {
this.data = data;
}
filter(predicate: (item: T) => boolean): Pipeline<T> {
const filteredData = this.data.filter(predicate);
return new Pipeline(filteredData);
}
map<U>(mapper: (item: T) => U): Pipeline<U> {
const mappedData = this.data.map(mapper);
return new Pipeline(mappedData);
}
flatMap<U>(mapper: (item: T) => U[]): Pipeline<U> {
const flatMappedData = this.data.flatMap(mapper);
return new Pipeline(flatMappedData);
}
toArray(): T[] {
return this.data;
}
}
// 使用示例
const data = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 40 },
];
const result = new Pipeline(data)
.filter((item) => item.age >= 30)
.map((item) => item.name)
.toArray();
console.log(result); // ['Bob', 'Charlie']