linq, lambda - poszukiwanie najbliższego punktu w zbiorze

0

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?

1
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.

1

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

0

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

2

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);

1 użytkowników online, w tym zalogowanych: 0, gości: 1