Машинописный эквивалент .Single (предикат) из. NET - PullRequest
0 голосов
/ 09 июля 2020

In. NET я могу:

var ls = new List<string>(1,2,3,3,3,4,5,6);

var x1 = ls.Single(x => x == 3); // throws exception because there are more elems of 3 defined in ls
var x2 = ls.SingleOrDefault(x => x==3) // Returns default of int (0) because there are more elems of 3 defined in ls
var x3 = ls.Single(x => x== 1) // returns 1

Единая документация:

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.single?view=netcore-3.1

Что будет с Typecript эквивалент?

Я работаю в последней версии Angular.

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Такую утилиту, к сожалению, придется написать самому. Это может выглядеть примерно так:

const single = <T>(list: T[], predicate: (element: T) => boolean): T => {
  const index = list.findIndex(predicate);
  if (index === -1) throw new RangeError('No value found');

  const trimmedList: T[] = list.slice(index + 1);
  const nextIndex = trimmedList.findIndex(predicate);
  if (nextIndex !== -1) throw new RangeError('Multiple values found');

  return list[index];
};

const predicate = (value: number) => value === 1;

// These should then behave just like Single in .NET
single([1, 2, 3, 4], predicate); // Will return 1
single([1, 1, 2, 3, 4], predicate); // Will throw 'Multiple values found'
single([2, 3, 4], predicate); // Will throw 'No value found'
1 голос
/ 09 июля 2020

Это не проблема TypeScript, а проблема EcmaScript: нет набора расширений Linq-y, но вы можете легко написать функцию, подобную этой:

const ls = [1, 2, 3, 3, 3, 4, 5, 6];

function single<T>(a: ReadonlyArray<T>, fallback?: T): T {
    if (a.length === 1) return a[0];
    if (a.length === 0 && fallback !== void 0) return fallback;
    throw new Error();
}

// *** Single-like ***

const s1 = single(ls.filter(x => x === 1));  //found one
console.log(s1);  //outputs 1

const s2 = single(ls.filter(x => x === 9));  //found none => throws
const s3 = single(ls.filter(x => x === 3));  //found many => throws

// *** SingleOrDefault-like (just add a valid fallback) ***

const s4 = single(ls.filter(x => x === 1), 0);  //found one
console.log(s4);

const s5 = single(ls.filter(x => x === 9), 0);  //found none => fallback
console.log(s5);

const s6 = single(ls.filter(x => x === 3), 0);  //found many => throws

Также проверьте Неизменяемая. JS библиотека, в которой нет single -функции, но очень близка к схеме Linq.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...