mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Moves out Comparator logic from inline completions to arrays.ts.
This commit is contained in:
parent
258ca4f8a2
commit
e3544ad159
|
@ -625,6 +625,46 @@ export function maxIndex<T>(array: readonly T[], fn: (value: T) => number): numb
|
|||
return maxIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparator `c` defines a total order `<=` on `T` as following:
|
||||
* `c(a, b) <= 0` iff `a` <= `b`.
|
||||
* We also have `c(a, b) == 0` iff `c(b, a) == 0`.
|
||||
*/
|
||||
export type Comparator<T> = (a: T, b: T) => number;
|
||||
|
||||
export function compareBy<TItem, TCompareBy>(selector: (item: TItem) => TCompareBy, comparator: Comparator<TCompareBy>): Comparator<TItem> {
|
||||
return (a, b) => comparator(selector(a), selector(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* The natural order on numbers.
|
||||
*/
|
||||
export const numberComparator: Comparator<number> = (a, b) => a - b;
|
||||
|
||||
/**
|
||||
* Returns the first item that is equal to or greater than every other item.
|
||||
*/
|
||||
export function findMaxBy<T>(items: readonly T[], comparator: Comparator<T>): T | undefined {
|
||||
if (items.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let min = items[0];
|
||||
for (const item of items) {
|
||||
if (comparator(item, min) > 0) {
|
||||
min = item;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first item that is equal to or less than every other item.
|
||||
*/
|
||||
export function findMinBy<T>(items: readonly T[], comparator: Comparator<T>): T | undefined {
|
||||
return findMaxBy(items, (a, b) => -comparator(a, b));
|
||||
}
|
||||
|
||||
export class ArrayQueue<T> {
|
||||
private firstIdx = 0;
|
||||
private lastIdx = this.items.length - 1;
|
||||
|
|
|
@ -354,6 +354,24 @@ suite('Arrays', () => {
|
|||
assert.strictEqual(arrays.maxIndex(array, value => value === 'b' ? 5 : 0), 1);
|
||||
});
|
||||
|
||||
test('findMaxBy', () => {
|
||||
const array = [{ v: 3 }, { v: 5 }, { v: 2 }, { v: 2 }, { v: 2 }, { v: 5 }];
|
||||
|
||||
assert.strictEqual(
|
||||
array.indexOf(arrays.findMaxBy(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
|
||||
1
|
||||
);
|
||||
});
|
||||
|
||||
test('findMinBy', () => {
|
||||
const array = [{ v: 3 }, { v: 5 }, { v: 2 }, { v: 2 }, { v: 2 }, { v: 5 }];
|
||||
|
||||
assert.strictEqual(
|
||||
array.indexOf(arrays.findMinBy(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
|
||||
2
|
||||
);
|
||||
});
|
||||
|
||||
suite('ArrayQueue', () => {
|
||||
suite('takeWhile/takeFromEndWhile', () => {
|
||||
test('TakeWhile 1', () => {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { compareBy, findMaxBy, numberComparator } from 'vs/base/common/arrays';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
@ -16,7 +17,6 @@ import { CompletionItem } from 'vs/editor/contrib/suggest/suggest';
|
|||
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
|
||||
import { minimizeInlineCompletion } from './inlineCompletionsModel';
|
||||
import { NormalizedInlineCompletion, normalizedInlineCompletionsEquals } from './inlineCompletionToGhostText';
|
||||
import { compareBy, compareByNumber, findMaxBy } from './utils';
|
||||
|
||||
export interface SuggestWidgetState {
|
||||
/**
|
||||
|
@ -108,7 +108,7 @@ export class SuggestWidgetInlineCompletionProvider extends Disposable {
|
|||
|
||||
const result = findMaxBy(
|
||||
candidates,
|
||||
compareBy(s => s!.prefixLength, compareByNumber())
|
||||
compareBy(s => s!.prefixLength, numberComparator)
|
||||
);
|
||||
return result ? result.index : - 1;
|
||||
}
|
||||
|
|
|
@ -11,23 +11,3 @@ export function createDisposableRef<T>(object: T, disposable?: IDisposable): IRe
|
|||
dispose: () => disposable?.dispose(),
|
||||
};
|
||||
}
|
||||
|
||||
export type Comparator<T> = (a: T, b: T) => number;
|
||||
|
||||
export function compareBy<TItem, TCompareBy>(selector: (item: TItem) => TCompareBy, comparator: Comparator<TCompareBy>): Comparator<TItem> {
|
||||
return (a, b) => comparator(selector(a), selector(b));
|
||||
}
|
||||
|
||||
export function compareByNumber(): Comparator<number> {
|
||||
return (a, b) => a - b;
|
||||
}
|
||||
|
||||
export function findMaxBy<T>(items: T[], comparator: Comparator<T>): T | undefined {
|
||||
let min: T | undefined = undefined;
|
||||
for (const item of items) {
|
||||
if (min === undefined || comparator(item, min) > 0) {
|
||||
min = item;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue