• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Js, jak wartość nie jest liczbą to wywal z tablicy.

VPS Starter Arubacloud
0 głosów
606 wizyt
pytanie zadane 20 listopada 2017 w JavaScript przez Vorex444 Dyskutant (9,610 p.)

Siema, chcę zrobić coś takiego.

Mam jakaś tablicę np.

var arr = [2, 10, 20, 'cos', 'cos2' '1'];

i chcę aby podana funkcja pobrała tablicę, posortowała, wywaliła wszystko co nie jest liczbą, a liczby wypisała.

Zrobiłem coś takiego, próbowałem dalej ale mi nie idzie. Najgorzej mi idzie usunięcie elementów które nie są liczbami, próbowałem warunek if arr[i]==NaN to wytnij, ale nie działało, może źle pisałem, jak wy byście to zrobili?

var arr = ["1", "test", 2, 10, 20, NaN, true, false];
function sortArr()
{
    arr.sort(function(a,b){return a-b});
    console.log(arr);
};
sortArr();

 

4 odpowiedzi

0 głosów
odpowiedź 20 listopada 2017 przez Tomek Sochacki Ekspert (227,510 p.)
edycja 21 listopada 2017 przez Tomek Sochacki

Podpowiedź: Array.prototype.filter, np:

const arr = ["1", "test", 2, 10, 20, NaN, true, false];

arr.filter( val => !isNaN( val ) && typeof val === 'number' );

Tylko w tej wersji odfiltruje także ciąg znakowy "1". Jeśli tak ma być to oki, jeśli nie to pokombinuj sobie z innym nieco warunkiem w metodzie filter (w razie czego daj swoją propozycję to poprawimy).

I taka mała podpowiedź - najpierw lepiej odfiltrować "zbędne" elementy, a dopiero potem sortować nową już tablicę. A tak na marginesie to pytanie skąd masz w ogóle taką mieszaną tablicę? Co prawda w JS jak najbardziej można takie tablice robić (de facto tablica to po prostu obiekt nieco bardziej specyficzny) ale w rzeczywistości często rodzi to więcej problemów niż korzyści. Także na początek zacznij od zweryfikowania czy na pewno chcesz mieszać w tablicy typ number z innymi? Bo ja szczerze mówiąc niezbyt widzę w tym przykładzie sens takiego mieszania...

Pozdrawiam

komentarz 20 listopada 2017 przez xmentor Nałogowiec (49,520 p.)
Można dorzucić jeszcze isNaN, bo w tablicy zostanie również NaN(po sortowaniu i filtrowaniu) - chyba że taki jest zamiar
komentarz 20 listopada 2017 przez xmentor Nałogowiec (49,520 p.)
Racja, sorki za niedopatrzenie
komentarz 20 listopada 2017 przez Vorex444 Dyskutant (9,610 p.)
var arr = ["1", "test", 2, 10, 20, NaN, true, false];

var sortArray = arr.filter(function(val){
    return typeof val == 'number';
});

console.log(sortArray.sort(function(a,b){return a-b}));

Zrobiłem tak, ale nie wiem jak pozbyć się NaN

1
komentarz 21 listopada 2017 przez kap Stary wyjadacz (11,620 p.)
edycja 21 listopada 2017 przez kap

@{Tomasz Sochacki} W ten sposób wywalisz z tablicy wszystkie zera, czyli prawidłowe liczby, powinno być:
 

arr.filter(val => !isNaN(val) && typeof val === 'number')

lub:
 

[1, 2, 0, NaN, 5].filter(val => val === val && typeof val === 'number')

 

komentarz 21 listopada 2017 przez Tomek Sochacki Ekspert (227,510 p.)
@kap kurde racja, zapomnialem o tym. duży plusik za znalezienie tak głupiego błędu, aż wstyd...
0 głosów
odpowiedź 20 listopada 2017 przez xmentor Nałogowiec (49,520 p.)

Użyj filter i isNaN

0 głosów
odpowiedź 20 listopada 2017 przez ProgramistaStepek Nałogowiec (27,020 p.)
0 głosów
odpowiedź 21 listopada 2017 przez kap Stary wyjadacz (11,620 p.)
edycja 21 listopada 2017 przez kap

chcę aby podana funkcja pobrała tablicę, posortowała, wywaliła wszystko co nie jest liczbą, a liczby wypisała

No i tu masz podstawowy błąd w założeniu - powinieneś dążyć do tego, by funkcje zwracały wartość, nie powinny mieć kilku odpowiedzialności, a już na pewno nie obliczenia i wyświetlanie wyniku jednocześnie. Idealnie byłoby to rozbić na kilka części - a dokładniej trzy bazowe funkcje (1: "posortowała", 2: "wywaliła wszystko co nie jest liczbą", 3: "wypisała"), które można ze sobą łączyć (jedna z nich jest wbudowana - console.log):


// funkcje bazowe:
const sortNumbers = arr => arr.sort((a, b) => a - b)

const filterNumbers = arr => arr
  .filter(item => !isNaN(item) && typeof item === 'number')

// funkcje złożone:
const getSortedNumbers = arr => sortNumbers(filterNumbers(arr))

const printNumbers = arr => console.log(getSortedNumbers(arr))

// przykład uzycia:
printNumbers([2, 1, 0, NaN, 'foo', {}, [], /^abc/, true, 7, 3])

Dzięki temu funkcje są maksymalnie reużywalne (komponowalne) i testowalne.
To, że w swoim przykładzie operujesz funkcją nie na argumencie a na zmiennej zewnętrznej sprawia, że funkcja jest "jednorazowa", czyli de facto bezużyteczna - równie dobrze mógłbyś wykonać obliczenia poza nią.

Ewentualnie jak komuś nie zalezy na maksymalnej reużywalności to taka wersja też ujdzie:

 

const getSortedNumbers = arr => arr
  .filter(item => !isNaN(item) && typeof item === 'number')
  .sort((a, b) => a - b)

Byle nie mieszać obliczeń i prezentacji wyniku!

 

PS

arr[i]==NaN

nie działa, bo:
 

NaN !== NaN

co jest może nieintuicyjne, ale jak najbardziej prawidłowe (to nie wtf JavaScriptu tylko standardowe zachowanie we wszystkich(?) językach programowania). NaN to wartość niezdefiniowana/niereprezentowalna, więc nie da się zrównać dwóch takich wartości, np:
 

Math.sqrt(-1)

i

Math.sqrt(-2)

nie mają rozwiązań w liczbach rzeczywistych, więc są zamieniane na NaN, ale nie można powiedzieć, że:
 

Math.sqrt(-1) === Math.sqrt(-2)

bo to matematycznie nie jest prawda (mają dwa rózne rozwiązania na liczbach zespolonych).

Co prawda:
 

Math.sqrt(-1) === Math.sqrt(-1)

jest prawdą, ale NaN nie przechowuje informacji o tym z jakiego działania powstał, dlatego założono, że NaN !== NaN zawsze.

Podobne pytania

+1 głos
1 odpowiedź 413 wizyt
0 głosów
1 odpowiedź 6,368 wizyt
0 głosów
1 odpowiedź 434 wizyt

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...