Znajdź obiekt, według zakresu wartości

Znajdź obiekt, według zakresu wartości
Gouda105
  • Rejestracja:prawie 8 lat
  • Ostatnio:około miesiąc
  • Postów:487
0

Witam,
załóżmy, że mam tablicę:

Kopiuj
const x = [{
        from: 0,
        to: 100,
        color: "red",
    },
    {
        from: 100,
        to: 200,
        color: "blue"
    }
]

i zmienną:

Kopiuj
const a = 50

i teraz chciałbym sprawdzić, jaki kolor jej odpowiada na podstawie zakresu, w jakim się znajduje. Kolor wyjdzie czerwony, bo jest większa od 0 (from) i mniejsza od 100 (to).

KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:4 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
1

w Scali bym napisał tak:

Kopiuj
x.filter(c => c.from <= a && a <c.to)

Jak znajdę czas to przepiszę do JSa

Update

Kopiuj
const x = [{
    from: 0,
    to: 100,
    color: "red",
  },
  {
    from: 100,
    to: 200,
    color: "blue"
  }
]
const a = 50
const color = x
  .filter(c => c.from <= a && a < c.to)
  .map(c => c.color)[0]
console.log(color)

Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 1x, ostatnio: KamilAdam
katakrowa
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1

Można tak:

Kopiuj
const a = 50 ;

const x = [{
        from: 0,
        to: 100,
        color: "red",
    },
    {
        from: 100,
        to: 200,
        color: "blue"
    }
]

let res = x.forEach ( (item)=>{  
  if ( ( a >= item.from ) && ( a <= item.to ) ){
    console.log ( 'Element spełnia warunek', item );
  }
} );

Lub tak:

Kopiuj
<script>
const a = 50 ;

const x = [{
        from: 0,
        to: 100,
        color: "red",
    },
    {
        from: 100,
        to: 200,
        color: "blue"
    }
]

let res = x.filter ( (item)=>{  
  if ( ( a >= item.from ) && ( a <= item.to ) ){
    return true;
  } else {
    return false
  }
} );

console.log ( 'Wynik:', res );
</script>

Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
LukeJL
1. wersja z forEach tylko wyświetla, ale nie zwraca wartości, więc nie będzie dało się jej użyć później (chyba, że przypiszemy ją do zmiennej zewnętrznej, ale to już brnięcie dalej w złe podejście 2. drugie podejście teoretycznie mogłoby być, ale ma dziwną nadmiarową konstrukcję typu if (condition) return true; else return false zamiast po prostu return condition
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:37 minut
  • Postów:8423
3
Kopiuj
const color = x
  .filter(c => c.from <= a && a < c.to)
  .map(c => c.color)[0]

jeśli zależy nam tylko na pierwszym elemencie, można użyć .find zamiast .filter.

Kopiuj
const color = x.find(c => c.from <= a && a < c.to).color;

jednak nawet używając .filter nie musimy używać map:

Kopiuj
const color = x.filter(c => c.from <= a && a < c.to)[0].color;

KamilAdam
find to to co mi zabrakło
Gouda105
  • Rejestracja:prawie 8 lat
  • Ostatnio:około miesiąc
  • Postów:487
0

Przepuściłem wasze propozycje przez testy wydajności i oczywiście wyszło, że

Kopiuj
const color = x.find(c => c.from <= a && a < c.to).color;

jest najszybsze. Tego właśnie potrzebowałem dziękuję.

https://jsbench.me/ihl5b0bhd1/1

LukeJL
bo find przestaje szukać, jak znajdzie. A np. z podejściem filter + map, to przeszedł przez wszystkie elementy tablicy, utworzył dodatkową tablicę (dodatkowy narzut), później map zrobiłoby to samo - przeszło przez wszystkie elementy i utworzyło by dodatkową tablicę. Przy 2 elementach to nie ma znaczenia, ale jakbyś miał np. setki tysięcy elementów i musiałbyś takie filtrowanie wykonywać często (np. ileś razy na sekundę), to już by mogło mieć znaczenie.
LukeJL
no i taka uwaga do benchmarków, to w wersji z .forEach wrzuciłeś bezpośrednio wersję z console.log, co już samo w sobie obniża wydajność (console.log to straszny zamulator), poza tym to nie ma wiele sensu. Żeby wersja z forEach byłaby równoważna do innych opcji, to musiałaby "zwracać" wartość (np. można by zrobić let result przed wywołaniem forEach, a w handlerze forEach zamiast console.log ( 'Element spełnia warunek', item ); dać result = item. I tak będzie to niewydajne podejście, ale nie aż tak jak z console.log
SP
Szalony Programista2
Te find to natywna funkcja, innymi metodami to trochę jak implementować wyszukiwanie wyrazu w tekście, porównywanie stringów tu się nie nadaje, bo najlepiej szukać tak długo, aż się pierwsze litera nie będzie zgadzać i wtedy porównać resztę, tu jest trochę podobnie, można jednym potokiem zrobić, albo rozbić na kilka.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.