UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 4.21 kB
{"version":3,"file":"heap-BAgaPbFD.cjs","names":["hasAtLeast"],"sources":["../src/internal/heap.ts"],"sourcesContent":["/**\n * Heap related utilities.\n */\n\nimport { hasAtLeast } from \"../hasAtLeast\";\nimport { swapInPlace } from \"./swapInPlace\";\nimport type { CompareFunction } from \"./types/CompareFunction\";\n\n/**\n * Mutates an array into a \"max\"-heap based on `compareFn` so that for any `item` in the heap, `compareFn(heap[0], item) > 0`.\n *\n * @param heap - The array to be heapified. The array would be mutated!\n * @param compareFn - The comparator used to order items in the heap. Use the\n * same function in all calls mutating the same heap otherwise you'd get\n * unexpected results.\n */\nexport function heapify<T>(\n // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- Intentional!\n heap: Array<T>,\n compareFn: CompareFunction<T>,\n): void {\n for (let i = Math.floor(heap.length / 2) - 1; i >= 0; i--) {\n heapSiftDown(heap, i, compareFn);\n }\n}\n\n/**\n * Insert an item into a heap if it's \"smaller\" (in regards to `compareFn`) than\n * the current head of the heap (which is the \"largest\" value in the heap). If\n * the item is inserted, the previous head of the heap is returned, otherwise\n * `undefined` is returned and the heap is unchanged.\n *\n * @param heap - A *mutable* array representing a heap (see `heapify`).\n * @param compareFn - The comparator used to order items in the heap. Use the.\n * @param item - The item to be inserted into the heap.\n * @returns `undefined` if the heap is unchanged, or the previous head of the\n * heap if the item was inserted.\n */\nexport function heapMaybeInsert<T>(\n // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- Intentional!\n heap: Array<T>,\n compareFn: CompareFunction<T>,\n item: T,\n): T | undefined {\n if (!hasAtLeast(heap, 1)) {\n return undefined;\n }\n\n const [head] = heap;\n\n if (compareFn(item, head) >= 0) {\n // The item shouldn't be inserted into the heap, the heap is unchanged.\n return undefined;\n }\n\n heap[0] = item;\n heapSiftDown(heap, 0, compareFn);\n return head;\n}\n\n/**\n * The main heap operation. Takes a `heap` and an `index` and sifts the item\n * down the heap until it reaches the correct position based on `compareFn`,\n * swapping other items in the process.\n */\nfunction heapSiftDown<T>(\n // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types -- Intentional!\n heap: Array<T>,\n index: number,\n compareFn: CompareFunction<T>,\n): void {\n let currentIndex = index;\n\n // The loop continues while the currentIndex has children in the heap.\n while (currentIndex * 2 + 1 < heap.length) {\n const firstChildIndex = currentIndex * 2 + 1;\n\n let swapIndex =\n compareFn(heap[currentIndex]!, heap[firstChildIndex]!) < 0\n ? // Is the parent \"smaller\" (in regards to `compareFn`) to its child?\n firstChildIndex\n : currentIndex;\n\n const secondChildIndex = firstChildIndex + 1;\n if (\n secondChildIndex < heap.length &&\n compareFn(heap[swapIndex]!, heap[secondChildIndex]!) < 0\n ) {\n // Is there a second child? Is it the smallest of the three?\n swapIndex = secondChildIndex;\n }\n\n if (swapIndex === currentIndex) {\n // We assume the array is a heap and the existing order of items satisfies\n // the compareFn so we can stop here.\n return;\n }\n\n swapInPlace(heap, currentIndex, swapIndex);\n\n currentIndex = swapIndex;\n }\n}\n"],"mappings":"qFAgBA,SAAgB,EAEd,EACA,EACM,CACN,IAAK,IAAI,EAAI,KAAK,MAAM,EAAK,OAAS,EAAE,CAAG,EAAG,GAAK,EAAG,IACpD,EAAa,EAAM,EAAG,EAAU,CAgBpC,SAAgB,EAEd,EACA,EACA,EACe,CACf,GAAI,CAACA,EAAAA,EAAW,EAAM,EAAE,CACtB,OAGF,GAAM,CAAC,GAAQ,EAEX,OAAU,EAAM,EAAK,EAAI,GAO7B,MAFA,GAAK,GAAK,EACV,EAAa,EAAM,EAAG,EAAU,CACzB,EAQT,SAAS,EAEP,EACA,EACA,EACM,CACN,IAAI,EAAe,EAGnB,KAAO,EAAe,EAAI,EAAI,EAAK,QAAQ,CACzC,IAAM,EAAkB,EAAe,EAAI,EAEvC,EACF,EAAU,EAAK,GAAgB,EAAK,GAAkB,CAAG,EAErD,EACA,EAEA,EAAmB,EAAkB,EAS3C,GAPE,EAAmB,EAAK,QACxB,EAAU,EAAK,GAAa,EAAK,GAAmB,CAAG,IAGvD,EAAY,GAGV,IAAc,EAGhB,OAGF,EAAA,EAAY,EAAM,EAAc,EAAU,CAE1C,EAAe"}