Mam taki problem, który chciałbym rozwiązać:
Mam kilka punktów, niech będą 1D, np X = {1, 4, 7, 9, 20}
mam też y = 5
chce znaleźć który element X jest najbliższy mojemu y.
Da się to jakoś zrobić odpowiednio sformułowanym zapytaniem?
var list = new List<int> { 1, 2, 7, 9, 20, -5 };
var find = -10;
var nearest = list[list
.Select((val, index) => new { index, val = Math.Abs(find - val) })
.OrderBy(x => x.val)
.First()
.index];
Console.WriteLine($"Najblizsza liczba: {nearest}");
Chociaż według mnie lepiej jest zrobić to "normalnie"
np. KeyValuePair lub Dictionary <Int, int> od wartosci Index i Math.Abs(find -x) i wybrać najmniejszą.
Albo napisać po prostu funkcję na zasadzie min/max, i chyba to podejście jest najlepsze jeżeli chodzi o wydajność, ale ręki nie dam.
możesz zrobić coś takiego
int[] tab = new int[] { 1, 4, 7, 9, 20 };
int max = tab.Where(x => x < 5).DefaultIfEmpty().Max();
int min = tab.Where(x => x > 5).DefaultIfEmpty().Min();
return 5 - max < min - 5 ? max : min;
ale ani to ładne ani wydajne. Wydajniej było by po prostu posortować tą tablicę, znaleźć punkt, gdzie zadana wartość powinna być i zobaczyć co jest bliżej - to po lewej czy po prawej
Dzięki za odpowiedzi, ale sobie sam też odpowiem. Nie w jednej linii i pewnie nie najwydajniej ale wydaje mi się najładniej. Kwestia gustu oczywiście :)
var X = new List<int> {1,4,7,9,20};
int y = 5;
int v = X.OrderBy(x => Math.Abs(x - y)).First(); //wartość
int idx = X.IndexOf(v); //index
Można też tak:
List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;
int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y);