Skip to content

Commit

Permalink
Add reduce iterables utility
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanHahn-Signal committed Jun 28, 2021
1 parent 7cf7b1f commit 4495a1a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
5 changes: 3 additions & 2 deletions ts/ConversationController.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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,
Expand Down
18 changes: 18 additions & 0 deletions ts/test-both/util/iterables_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
groupBy,
isIterable,
map,
reduce,
size,
take,
} from '../../util/iterables';
Expand Down Expand Up @@ -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 = {
Expand Down
12 changes: 12 additions & 0 deletions ts/util/iterables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 4495a1a

Please sign in to comment.