Add reduce
iterables utility
This commit is contained in:
parent
7cf7b1fca5
commit
4495a1ac67
3 changed files with 33 additions and 2 deletions
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { debounce, reduce, uniq, without } from 'lodash';
|
||||
import { debounce, uniq, without } from 'lodash';
|
||||
import PQueue from 'p-queue';
|
||||
|
||||
import dataInterface from './sql/Client';
|
||||
|
@ -13,6 +13,7 @@ import { SendOptionsType, CallbackResultType } from './textsecure/SendMessage';
|
|||
import { ConversationModel } from './models/conversations';
|
||||
import { maybeDeriveGroupV2Id } from './groups';
|
||||
import { assert } from './util/assert';
|
||||
import { map, reduce } from './util/iterables';
|
||||
import { isGroupV1, isGroupV2 } from './util/whatTypeOfConversation';
|
||||
import { deprecated } from './util/deprecated';
|
||||
import { getSendOptions } from './util/getSendOptions';
|
||||
|
@ -103,7 +104,7 @@ export function start(): void {
|
|||
};
|
||||
|
||||
const newUnreadCount = reduce(
|
||||
this.map((m: ConversationModel) =>
|
||||
map(this, (m: ConversationModel) =>
|
||||
canCount(m) ? getUnreadCount(m) : 0
|
||||
),
|
||||
(item: number, memo: number) => (item || 0) + memo,
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
groupBy,
|
||||
isIterable,
|
||||
map,
|
||||
reduce,
|
||||
size,
|
||||
take,
|
||||
} from '../../util/iterables';
|
||||
|
@ -311,6 +312,23 @@ describe('iterable utilities', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('reduce', () => {
|
||||
it('returns the accumulator when passed an empty iterable', () => {
|
||||
const fn = sinon.fake();
|
||||
|
||||
assert.strictEqual(reduce([], fn, 123), 123);
|
||||
|
||||
sinon.assert.notCalled(fn);
|
||||
});
|
||||
|
||||
it('iterates over the iterable, ultimately returning a result', () => {
|
||||
assert.strictEqual(
|
||||
reduce(new Set([1, 2, 3, 4]), (result, n) => result + n, 89),
|
||||
99
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('take', () => {
|
||||
it('returns the first n elements from an iterable', () => {
|
||||
const everyNumber = {
|
||||
|
|
|
@ -155,6 +155,18 @@ class MapIterator<T, ResultT> implements Iterator<ResultT> {
|
|||
}
|
||||
}
|
||||
|
||||
export function reduce<T, TResult>(
|
||||
iterable: Iterable<T>,
|
||||
fn: (result: TResult, value: T) => TResult,
|
||||
accumulator: TResult
|
||||
): TResult {
|
||||
let result = accumulator;
|
||||
for (const value of iterable) {
|
||||
result = fn(result, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function take<T>(iterable: Iterable<T>, amount: number): Iterable<T> {
|
||||
return new TakeIterable(iterable, amount);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue