src/nsmallest.js
- import {min} from '@iterable-iterator/reduce';
- import {sorted} from '@iterable-iterator/sorted';
- import {forwardRangeIterator} from '@iterable-iterator/range';
- import {iter} from '@iterable-iterator/iter';
- import {_zip2} from '@iterable-iterator/zip';
- import {reversed} from '@total-order/reversed';
-
- import {keeporder} from './core/index.js';
-
- import heapify from './heapify.js';
- import heapreplace from './heapreplace.js';
-
- export default function nsmallest(compare, n, iterable) {
- if (n === 1) {
- const sentinel = {};
-
- const result = min(compare, iterable, sentinel);
-
- return result === sentinel ? [] : [result];
- }
-
- if (iterable.length !== undefined && n >= iterable.length)
- return sorted(compare, iterable);
-
- const it = iter(iterable);
-
- const result = Array.from(
- _zip2(forwardRangeIterator(0, n, 1), it),
- ([i, elem]) => [elem, i],
- );
-
- if (result.length === 0) return result;
-
- const h = heapify(keeporder(reversed(compare)), result);
-
- let top = result[0][0];
-
- let order = n;
-
- for (const elem of it) {
- if (compare(elem, top) < 0) {
- heapreplace(h, [elem, order]);
-
- top = result[0][0];
-
- ++order;
- }
- }
-
- return sorted(
- compare,
- Array.from(result, (r) => r[0]),
- );
- }