Przypsianie kilku zmiennym wartości z tablicy

Przypsianie kilku zmiennym wartości z tablicy
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Bo pomyślałem sobie żeby stworzyć jakiegoś pustego stringa do którego będą trafiać kolejne pytania. Jednak chciałbym utworzyć też jakąś pustą tablice do której bym wrzucił pytania z tablicy pierwotnej, a następnie to porównywać ze sobą te dwie tablice a następnie odrębne pytania wrzucać do tego pustego stringa

P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Napisałem taki kod ale za każdym razem jest ciągle ostatnie pytanie https://jsfiddle.net/3wncq2kd/. I nie jestem do końca pewny czy z tym innerHTML tak można robić

szatkus
Piszesz 4 razy do innerHTML, każdy przypisanie nadpisuje poprzednie. Czego innego się spodziewałeś?
P1
Wiem. Ale czasami chce poeksperymentować z kodem żeby zobaczyć tego efekt
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Nie bardzo wiem, jak poprawić Twój kod, gdyż robi on w zasadzie coś innego, niż piszesz, że chcesz zrobić. Zobacz:

Kopiuj
const headQuestions = document.getElementById('header-questions');

Pobierasz element HTML, w którym umieścisz pytanie. Poprawnie.

Kopiuj
headQuestions.innerHTML = 'What is the most used programming language in 2019?';
headQuestions.innerHTML = 'Who is the President of US?';
headQuestions.innerHTML = 'What does HTML stand for?';
headQuestions.innerHTML = 'What year was JavaScript launched?';

Przypisujesz cztery razy do tej samej zmiennej. Dlatego też za każdym odświeżeniem strony właściwość innerHTML zmiennej headQuestions będzie mieć wartość "What year was JavaScript launched?" Napisał już o tym @szatkus w komentarzu wyżej.

Kopiuj
  let questArr = [
    'What is the most used programming language in 2019?',
    'Who is the President of US?',
    'What does HTML stand for?',
    'What year was JavaScript launched?'
  ];

Tworzysz tablicę z pytaniami. Poprawnie.

Kopiuj
  let questStr = 'header-questions';

Zapisujesz ID elementu HTML do pobrania i umieszczenia w nim pytania. Teoretycznie poprawnie – zakładając, że usuniesz kod, o którym pisałem powyżej, a po prostu wywołasz funkcję.

Kopiuj
  let copyQuestArr = [];
  for (let i = 0; i < questArr.length; i++) {
    copyQuestArr.push(questArr[i]);
  }

Kopiujesz pytania z jednej tablicy do drugiej. Nie wiem, czemu to robisz; moim zdaniem nie ma to związku z wyświetlaniem losowego pytania.

Kopiuj
  for (const i in copyQuestArr) {
    var elArrs = document.getElementById(questStr);
    elArrs = copyQuestArr[i].innerHTML = questArr[i];
  }

Dla każdego pytania robisz dwie rzeczy. Najpierw pobierasz element HTML, w którym je chcesz umieścić. Następnie wykonujesz dwa przypisania: najpierw właściwości copyQuestArr[i].innerHTML przypisujesz wartość questArr[i], a potem zmiennej elArrs przypisujesz wartość, którą zwraca przypisanie copyQuestArr[i].innerHTML = questArr[i] – czyli też wartość questArr[i] (jeśli chcesz wiedzieć, czemu tak jest, poczytaj to -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#precedence_and_associativity). Gdybyś tę funkcję wywołał, wartość właściwości innerHTML pobranego elementu HTML byłaby po wywołaniu zawsze ostatnim pytaniem.

Kopiuj
  return elArrs;

Zwracasz wartość zmiennej, która nie jest zadeklarowania bezpośrednio w bloku ciała funkcji. Gdybyś wywołał tę funkcję, to by zadziałało (najprawdopodobniej z uwagi na tzw. hoisting – https://developer.mozilla.org/en-US/docs/Glossary/Hoisting), jednak nie jest to dobrze napisany kod. Z jedną zmienną można jeszcze dojść, co się dzieje, ale gdybyś takich zmiennych miał 10 w jednym pliku, czytałbyś go pewnie dwa razy dłużej, żeby zrozumieć, co się dzieje w kodzie. W takim przypadku jak Twój zmienna, której wartość jest zwracana, powinna zostać zadeklarowana bezpośrednio w bloku ciała funkcji.

Poza tym nigdzie funkcji nie wywołujesz.


UPDATE Żeby zrobić to, czego oczekujesz, czyli wyświetlić za każdym odświeżeniem strony nowe pytanie, to najprościej będzie chyba tak:

  1. Pobierasz element HTML, w którym umieścisz pytanie (to już masz).
  2. Tworzysz tablicę z pytaniami (to już masz).
  3. Losujesz liczbę całkowitą z przedziału [0, rozmiar tablicy z pytaniami - 1], korzystając z metody Math.random() (to trzeba by jeszcze zrobić).
  4. Przypisujesz właściwości innerHTML pobranego elementu HTML ten element tablicy, którego indeks jest równy wylosowanej liczbie (to trzeba by jeszcze zrobić).

UPDATE2 Żeby na każde naciśnięcie przycisku Wyślij pojawiało się nowe pytanie, ale bez odświeżania strony, to najprościej chyba będzie tak:

  1. Wykonujesz te cztery punkty, które napisałem wyżej.
  2. Kod, który powstał po ich wykonaniu, umieszczasz w nowej funkcji. Funkcja nie powinna pobierać argumentów ani zwracać niczego.
  3. Tę nową funkcję wywołujesz przy zdarzeniu onclick przycisku Wyślij. Zobacz na przykład: https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event

Pamiętaj, że przy tak niewielkiej liczbie pytań i takim podejściu czasem to samo pytanie może być wyświetlone 2 lub 3 razy pod rząd. Jeśli chciałbyś tego uniknąć, powinieneś dodatkowo:

  1. utworzyć zmienną globalną (to znaczy poza jakąkolwiek funkcją);
  2. w funkcji uruchamianej po naciśnięciu przycisku losować indeks tak długo, aż będzie on różny od wartości tej zmiennej; możesz tutaj wykorzystać np. pętlę do-while – możesz zmodyfikować na przykład kod z mojego poprzedniego posta: https://4programmers.net/Forum/JavaScript/349748-przypsianie_kilku_zmiennym_wartosci_z_tablicy?p=1749451#id1749451
  3. po wylosowaniu przypisywać tej zmiennej wylosowany indeks.

edytowany 9x, ostatnio: Silv
P1
Ok. Tylko chce na razie zrobić tak żeby za każdym kliknięciem przycisku wyślij zmienić pytanie na inne
Silv
No tak, to te 4 punkty wyjaśniają.
Silv
PS Aha, nie, dobra, już rozumiem, o co Ci chodzi.
Silv
PS2 Dodałem UPDATE2 w tym poście, zobacz.
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Napisałem kod https://jsfiddle.net/n29dr485/ do tych czterech punktów
Pobierasz element HTML, w którym umieścisz pytanie (to już masz).
Tworzysz tablicę z pytaniami (to już masz).
Losujesz liczbę całkowitą z przedziału [0, rozmiar tablicy z pytaniami - 1], korzystając z metody Math.random() (to trzeba by jeszcze zrobić).
Przypisujesz właściwości innerHTML pobranego elementu HTML ten element tablicy, którego indeks jest równy wylosowanej liczbie (to trzeba by jeszcze zrobić)
ale pojawia mi się komunikat element is null. Zastanawiam się co jest nie tak. Analizuje ale nic z tego
Ok poprawiłem https://jsfiddle.net/f46bnt7u/2/. Czy w tej funkcji jest teraz wszystko ok jeśli chodzi o powyższe cztery punkty czy powinieniem coś poprawić?

edytowany 2x, ostatnio: piotrek1998
szatkus
Znowu zapodajesz kod, który niczego nie robi. Może zainwestuj w korki?
P1
Dzięki za dobrą radę
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Jeśli chodzi o powyższe cztery punkty, jest OK. (Tym niemniej widzę kilka mniej ważnych rzeczy niezwiązanych z nimi, które można by poprawić).


edytowany 1x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Czy teraz ta funkcja jest ok? Bo chciałbym przejść dalej do pisania kodu nie ukrywam ale zanim to nastąpi chciałbym się upewnić czy tutaj jest wszystko ok?

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

Lepiej. :) Jeśli już chcesz ulepszać, to jeszcze:

  1. Kod const btnSubmit = document.querySelector('button'); – pobiera pierwszy element HTML <button> na stronie. Teraz ten kod działa, ale jak np. dodasz kolejny przycisk (np. Anuluj :P ), to przestanie. Lepiej, żebyś przyciskowi do wysyłania formularza dodał klasę i na podstawie nazwy tej klasy go pobierał, a nie na podstawie jego "typu".
  2. Nazwa zmiennej funkcji questQuiz – istnieje taka konwencja, że nazwy metod i funkcji opisuje się czasownikami, coś na kształt trybu rozkazującego. Nie wiem, czy tutaj ją zastosowałeś? – bo zarówno "quest", jak i "quiz" jest i rzeczownikiem, i czasownikiem. Moim zdaniem lepiej by brzmiało: getRandomQuestion, nie wiem, czy się zgodzisz.

edytowany 1x, ostatnio: Silv
Silv
PS Jeśli planujesz dodać jakąś inną funkcjonalność poza pobieraniem pytania w funkcji questQuiz, to oczywiście nazwa zaproponowana przeze mnie nie będzie dobra.
P1
Ta funkcja my tylko zmieniać pytanie na inne za każdym razem kiedy użytkownik wciśnie przyciks submit. Tylko tyle
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

I teraz tworze zmienną globalną do której początkowo przypisuje wartość 0? Pytam odnośnie tego

utworzyć zmienną globalną (to znaczy poza jakąkolwiek funkcją);
w funkcji uruchamianej po naciśnięciu przycisku losować indeks tak długo, aż będzie on różny od wartości tej zmiennej; możesz tutaj wykorzystać np. pętlę do-while – możesz zmodyfikować na przykład kod z mojego poprzedniego posta: Przypsianie kilku zmiennym wartości z tablicy
po wylosowaniu przypisywać tej zmiennej wylosowany indeks.
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

Jeśli chcesz mieć pewność za każdym razem innego pytania, to tworzysz taką zmienną, tak. Natomiast nie będzie dobrze przypisać do niej wartości 0. Dlaczego? Dlatego, że ta zmienna reprezentuje indeks, indeksować można wartością 0 (w JavaScripcie), a wartość początkowa tej zmiennej powinna być różna od każdego możliwego indeksu. Teoretycznie mógłbyś przypisać do niej jakąkolwiek wartość poza zbiorem wartości indeksu (zbiór wartości indeksu dla każdej tablicy w JavaScripcie to [0, długość tablicy - 1]). W praktyce najbardziej intuicyjnie jest przypisać do niej -1.

Jeszcze: dlaczego wartość początkowa tej zmiennej powinna być różna od każdego możliwego indeksu (w tablicy pytań)? Dlatego, że przypisując jakiś możliwy indeks nigdy go nie wylosujesz nie wylosujesz go podczas wyświetlania pierwszego pytania. Oczywiście piszę to w kontekście tej pętli, którą ja zaproponowałem. Jeśli byś takiej pętli nie zrobił, to być może mogłaby być to wartość indeksu, to już zależałoby od kodu.


PS W zasadzie w JavaScripcie być może lepiej niż -1 byłoby przypisać undefined. W sumie nie jestem pewien. Ty przypisz -1 – dla Twojego zastosowania jest wystarczająco dobre.


UPDATE Poprawiłem błąd.


edytowany 5x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

A odnośnie tego w funkcji uruchamianej po naciśnięciu przycisku losować indeks tak długo, aż będzie on różny od wartości tej zmiennej; możesz tutaj wykorzystać np. pętlę do-while to zrobić w jakiejś nowej funkcji czy w tej?

Kopiuj
btnSubmit.addEventListener('click', function() {
	answerQuiz(), randomAnswersQuiz();
});
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Generalnie nie ma znaczenia, czy kod pętli umieścisz w funkcji anonimowej będącej handlerem zdarzenia click, czy w funkcji "nie-anonimowej", którą dopiero umieścisz w tej funkcji anonimowej. Ja bym jednak radził, żebyś wszystko zrobił w funkcji "nie-anonimowej" (czyli tej pobierającej pytanie – już trochę pogubiłem się w nazwach u Ciebie), a w funkcji anonimowej umieścił jedynie samo wywołanie tej funkcji.


P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Szczerze powiedziawszy mam problem z napisaniem tego: w funkcji uruchamianej po naciśnięciu przycisku losować indeks tak długo, aż będzie on różny od wartości tej zmiennej; możesz tutaj wykorzystać np. pętlę do-while – możesz zmodyfikować na przykład kod z mojego poprzedniego posta. Powstaje mi pętla nieskończona

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Kod na kształt tego umieść w funkcji (pisałem z głowy):

Kopiuj
const questions = [ /* tu pytania */ ];
let oldIndex = -1;
let index = -1;

do {
    index = Math.floor(Math.random() * questions.length);
} while(index === oldIndex);

oldIndex = index;

edytowany 4x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Wiesz co luknąłbyś bo to jest ten kod

Kopiuj
function getRandomQuestion() {
	const headQuestions = document.getElementById('header-questions');
	let questArr = [
		'What is the most used programming language in 2019?',
		'Who is the President of US?',
		'What does HTML stand for?',
		'What year was JavaScript launched?'
	];
	do {
		var randomQuestIndex = Math.floor(Math.random() * questArr.length);
	} while (randomQuestIndex === randomIndex);
	randomIndex = randomQuestIndex;
	headQuestions.innerHTML = questArr[randomQuestIndex];
}

ale pare razy mi sie powtarzają po sobie pytania

P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Powtarzają się najpewniej dlatego, że masz podwójne wywołanie funkcji. Zauważ, że zmienna randomIndex jest "zewnętrzna" w stosunku do obu wywołań. W związku z tym wykonanie kodu jest takie:

Po załadowaniu/przeładowaniu strony:

  1. Zmienna randomIndex otrzymuje wartość -1.

Po pierwszym kliknięciu na przycisk "Wyślij":

  1. Uruchamiane jest wywołanie zdefiniowane za pomocą atrybutu onclick.
  2. Zmienna randomIndex otrzymuje jakąś wartość różną od jej obecnej wartości, czyli różną od -1. Oznaczmy tę nową wartość x1.
  3. Właściwość innerHTML elementu headQuestions przechowuje teraz pytanie o indeksie x1. Tego pytania nie widzisz, bo dalszy kod za szybko się wykonuje.
  4. Wywołanie jest kończone.
  5. Uruchamiane jest wywołanie zdefiniowane w funkcji addEventListener.
  6. Zmienna randomIndex otrzymuje jakąś wartość różną od jej obecnej wartości, czyli różną od x1. Oznaczmy tę nową wartość y1.
  7. Właściwość innerHTML elementu headQuestions przechowuje teraz pytanie o indeksie y1. To pytanie widzisz.
  8. Wywołanie jest kończone.

Po drugim kliknięciu na przycisk "Wyślij":

  1. Uruchamiane jest wywołanie zdefiniowane za pomocą atrybutu onclick.
  2. Zmienna randomIndex otrzymuje jakąś wartość różną od jej obecnej wartości, czyli różną od y1. Oznaczmy tę nową wartość x2.
  3. Właściwość innerHTML elementu headQuestions przechowuje teraz pytanie o indeksie x2. Tego pytania nie widzisz, bo dalszy kod za szybko się wykonuje.
  4. Wywołanie jest kończone.
  5. Uruchamiane jest wywołanie zdefiniowane w funkcji addEventListener.
  6. Zmienna randomIndex otrzymuje jakąś wartość różną od jej obecnej wartości, czyli różną od x2. Oznaczmy tę nową wartość y2.
  7. Właściwość innerHTML elementu headQuestions przechowuje teraz pytanie o indeksie y2. To pytanie widzisz.
  8. Wywołanie jest kończone.

Zauważ, że wartości y1 oraz y2 mogą być takie same.

Rozwiązaniem jest usunięcie jednego z wywołań funkcji. Sugerowałbym usunięcie wywołania zdefiniowanego w atrybucie onclick.


P1
No tak w sumie masz racje. Tyle że to nie do końca jest spowodowane błędem w mojej niewiedzy tylko nie do końca przemyślanej koncepcji działania aplikacji. Ale tak czy siak dzięki. Mogę dodać że jeden z nielicznych na tym forum potrafisz udzielić fachowej pomocy i chętnie dzielisz się wiedzą za co ogromny szacun. Naprawde.
Silv
Spoko. Sam uważam, że niewiele wiem, ale to, co wiem, staram się jakoś wykorzystać, by pomóc.
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Ok teraz działa. Tylko problem jest jeszcze jeden. Mianowicie gdy załaduje się za pierwszy razem aplikacja https://jsfiddle.net/5y1xhba3/ to w miejscu pytania jest widoczny napis Question. A gdybym tak chciał użytkownikowi pokazać Od razu jakieś dowolne pytanie to co musiałbym zrobić? Użyć zdarzenia DOMContentLoaded?

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Kiedyś w JSFiddle było tak: https://stackoverflow.com/a/35131116/4752834 – zwróć uwagę na zrzut ekranu. To znaczy, można było wybrać sobie w opcjach zdarzenie, na które ma być uruchamiany kod JavaScript. Dziś tej opcji nie mogę znaleźć. Ale: kod pod linkiem w pytaniu pod tym linkiem działa przy zdarzeniu DOMContentLoaded, ale nie przy zdarzeniu load. W związku z tym domyślam się, że automatycznie Twój kod uruchamiany jest na zdarzenie load. Możesz więcej poczytać -> https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event W skrócie: zdarzenie load jest wywoływane po zdarzeniu DOMContentLoaded. Co najprawdopodobniej oznacza, że nie o te dwa zdarzenia chodzi w Twoim kodzie.

Zauważ, że wywołujesz funkcję getRandomQuestion(); tylko na zdarzenie click. Powinieneś dodać wywołanie tej funkcji jeszcze raz, w zasięgu globalnym. Czyli na przykład tak (podaję kod, bo tak najprościej mi wytłumaczyć):

Kopiuj
getRandomQuestion(); // <- To dodajesz

btnSubmit.addEventListener('click', function() {
  answerQuiz(), randomAnswersQuiz(), getRandomQuestion();
});

edytowany 1x, ostatnio: Silv
P1
Też się zastanawiałem nad rozwiązanie zaproponowanym przez Ciebie. Jak zwykle twoja wiedza okazała się bezcenna. Dzięki wielkie
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Teraz zastanawiam się nad taką jedną rzeczą. Bo w sumie już ta aplikacja jest niemal gotowa bo to co chciałem do tej pory w niej zaimplementować to to zrobiłem. Natomiast pozostał mi jeszcze jedne problem do rozwikłania. Mianowicie na każe postawione użytkownikowi pytanie zmieniać warianty odpowiedzi tak jak to jest w tym quizie https://10projects10hours.netlify.app/quiz-app/index.html. Zastanwiam się po prostu czy aby nie utworzyć jakiegoś obiektu np. w tej funkcji który by przetrzymywał wszystkie warianty odpowiedzi. Czy to jest dobry krok w tym kierunku? Lub ewentualnie pomyślałem jeszcze nad tablicą wielowymiarową?

edytowany 1x, ostatnio: piotrek1998
Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
0

A jakby to miało wyglądać w kodzie? Pokaż któreś z tych rozwiązań.


edytowany 1x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Przyszło mi do głowy jeszcze jeden pomysł. Mianowicie kiedy użytkownikowi wyświetli się jakieś pytanie np. What is the most used programming language in 2019? i pojawią mu się te warianty odpowiedzi Java, C, Python, JS, to teraz mam dwie fukcje

Kopiuj
function answerQuiz() {
	let arrAnswersQuiz = [ 'Java', 'C', 'Python', 'JS' ];
	let arrVariantsAns = [ 'a', 'b', 'c', 'd' ];
	for (const i in arrVariantsAns) {
		var elements = (document.getElementById(arrVariantsAns[i]).innerHTML = arrAnswersQuiz[i]);
	}
	return elements;
}
Kopiuj
function randomAnswersQuiz() {
	const answers = [ 'Java', 'C', 'Python', 'JS' ];
	for (const id of [ 'a', 'b', 'c', 'd' ]) {
		const element = document.getElementById(id);
		const answerIndex = Math.floor(Math.random() * answers.length);
		element.innerText = answers[answerIndex];
		answers.splice(answerIndex, 1);
	}
}

które trzymają te odpowiedzi na to pytanie. Teraz gdy użytkonik zaznaczy jakąś odpowiedź na to pytanie i kliknie przycisk wyślij to pojawi mu się następne pytanie które brzmi: Who is the President of US?. I w tym momencie nie mogę mieć w tablicach obu funkcji do tego pytania odpowiedzi typu Java, C, Python, JS tylko

Kopiuj
function answerQuiz() {
	let arrAnswersQuiz = ['Florin Pop', 'Donald Trump', 'Ivan Saldano', ' Mihai Andrei'];
	let arrVariantsAns = [ 'a', 'b', 'c', 'd' ];
	for (const i in arrVariantsAns) {
		var elements = (document.getElementById(arrVariantsAns[i]).innerHTML = arrAnswersQuiz[i]);
	}
	return elements;
}
Kopiuj
function randomAnswersQuiz() {
	const answers = ['Florin Pop', 'Donald Trump', 'Ivan Saldano', ' Mihai Andrei'];
	for (const id of [ 'a', 'b', 'c', 'd' ]) {
		const element = document.getElementById(id);
		const answerIndex = Math.floor(Math.random() * answers.length);
		element.innerText = answers[answerIndex];
		answers.splice(answerIndex, 1);
	}
}

i na stronie odnośnie tego pytania nie wyświetlam użytkownikowi już Java,C,Python,JS tylko Florin Pop, Donald Trump, Ivan Saldano i Mihai Adnrei i tak za każdym razem z innym pytanie i zestawem odpowiedzi

P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Mógłbym zastosować opisane prze zemnie rozwiązanie czy raczej jest ono do kitu?

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Ale nie pokazałeś teraz rozwiązania, tylko opisałeś problem. Problem rozumiem. Pisałeś, że chcesz albo (1) zastosować obiekt, albo (2) tablicę wielowymiarową. Według mnie mogłyby te dwa rozwiązania wyglądać tak:

  1. Każde pytanie opakowujesz oddzielny w obiekt:

    Kopiuj
    const questions = [
        {
            content = "<question1's content>",
            answers = [
                "<question1's answer1>",
                "<question1's answer2>",
                ...
            ]
        },
        {
            content = "<question2's content>",
            answers = [
                ...
            ]
        },
        ...
    ];
    
  2. Każde pytanie wraz z odpowiedziami opakowujesz w oddzielną tablicę:

    Kopiuj
    const questions = [
        [
            "<question1's content>",
            [
                "<question1's answer1>",
                "<question1's answer2>",
                ...
            ]
        ],
        [
            "<question2's content>",
            [
                ...
            ]
        ],
        ...
    ];
    

Oczywiście może pewnie być kilka innych sposobów, ale te dwa są najbardziej intuicyjne w Twoim przypadku. Pierwszy z nich, z obiektami, jest według mnie bardziej intuicyjny, polecam Ci go. Tablica questions powinna być w zasięgu globalnym.

Z innych możliwości – mógłbyś korzystać z usługi sieciowej; wtedy, zamiast korzystać z tablicy o zasięgu globalnym, mógłbyś w każdym wywołaniu funkcji robić żądanie do API tej usługi, które by zwracało odpowiedzi dla danego pytania. Jednak myślę, że to zbyt rozbudowane jak na potrzeby tego projektu. Możesz spróbować pomyśleć o tym w przyszłości, jak będziesz uczyć się już konkretnie backendu.


edytowany 8x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Dla takiego obiektu jaki mi tu powstał

Kopiuj
let questArr = [
	{
		question: 'What is the most used programming language in 2019?',
		answers: [ 'Java', 'C', 'Python', 'JS' ]
	},
	{
		question: 'Who is the President of US?',
		answers: [ 'Florin Pop', 'Joe Biden', 'Ivan Saldano', 'Mihai Andrei' ]
	},
	{
		question: 'What does HTML stand for?',
		answers: [
			'Hypertext Markup Language',
			' Cascading Style Sheet',
			'Jason Object Notation',
			'Helicopters Terminals Motorboats Lamborginis'
		]
	},
	{
		question: 'What year was JavaScript launched?',
		answers: [ '1996', '1995', '1994', 'none of the above' ]
	}
];

musiałbym teraz użyć pętli for in lub pętli zagnieżdżonej

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Do tej pory również miałeś pętle, więc myślę, że to będzie coś podobnego. Opakowanie odpowiedzi w "obiekt pytania" nie powinno zmienić wiele. Jedyna większa zmiana moim zdaniem to taka, że powinieneś losować odpowiedzi w funkcji losującej pytanie (a nie oddzielnie od niej).

Przy okazji: moim zdaniem pętla for-of ma bardziej intuicyjne zachowanie niż pętla for-in, i dlatego polecałbym Ci tę pierwszą. Możesz ocenić sam: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of#difference_between_for...of_and_for...in (chociaż żeby te różnice zrozumieć, to trzeba rozumieć, jak działa dziedziczenie w JavaScripcie).


edytowany 4x, ostatnio: Silv
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Tak się zastanawiam czy nie wyrzucić z tych funkcji

Kopiuj
function answerQuiz() {
	let arrAnswersQuiz = [ 'Java', 'C', 'Python', 'JS' ];
	let arrVariantsAns = [ 'a', 'b', 'c', 'd' ];
	for (const i in arrVariantsAns) {
		var elements = (document.getElementById(arrVariantsAns[i]).innerHTML = arrAnswersQuiz[i]);
	}
	return elements;
}

function randomAnswersQuiz() {
	const answers = [ 'Java', 'C', 'Python', 'JS' ];
	for (const id of [ 'a', 'b', 'c', 'd' ]) {
		const element = document.getElementById(id);
		const answerIndex = Math.floor(Math.random() * answers.length);
		element.innerText = answers[answerIndex];
		answers.splice(answerIndex, 1);
	}
}

tych tablic let arrAnswersQuiz = [ 'Java', 'C', 'Python', 'JS' ] i const answers = [ 'Java', 'C', 'Python', 'JS' ]. No bo skoro jest to teraz w obiekcie...?

Silv
Moderator Wiki
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa
1

Generalnie – tak. W funkcji nie powinieneś mieć żadnych danych, bo taki obiekt, o jakim mówimy, ma już w sobie wszystkie potrzebne dane.

Druga sprawa, że być może łatwiej Ci będzie nie zmieniać tych funkcji, które już masz (one działają, więc po co je zmieniać). Usunąłbyś same ich wywołania, a napisałbyś nową funkcję (która będzie podoba do tych poprzednich, ale inna, bo będzie korzystać z nowego obiektu).


edytowany 2x, ostatnio: Silv
Zobacz pozostałe 5 komentarzy
Silv
Moim zdaniem lepiej będzie już nie korzystać z tego, co napisałeś, a zachować to tylko po to, żebyś np. mógł sobie to samemu poczytać, zobaczyć w przyszłości, jakbyś czegoś zapomniał. Ale jeśli chcesz zostać przy tym, to możesz równie dobrze zmodyfikować juz napisane funkcje – tylko wtedy chyba nie ma sensu pisać nowej.
P1
Silv
A napisałbyś kiedyś, że się ze mną nie zgadzasz. :P
Silv
OK, jeśli tak uważasz. ;)
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Próbuje w tej nowej funkcji napisać sobie(oczywiście z wykorzystaniem tego nowego obiektu) żeby losowało pytanie lecz coś nie chce pyknąć

Silv
To pokaż kod. ;)
P1
No bo ogólnie rzecz biorąc mam teraz obiekt w tablicy więc pierwsze co robie to chce za pomocą pętli for in przejść po tym obiekcie
Silv
Bez kodu trudno mi cokolwiek powiedzieć.
P1
  • Rejestracja:ponad 7 lat
  • Ostatnio:2 miesiące
  • Postów:639
0

Na razie tylko tyle

Kopiuj
function getRandomVariants() {
	for (let value in quizArr) {
		headQuestions.innerHTML = quizArr[value].question;
	}
}
Zobacz pozostały 1 komentarz
P1
No dobrze ale w jaki inny sposób mam przejść po elementach obiektu w tablicy jak nie pętlą?
szatkus
Po co przechodzić? Przecież potrzebujesz jedno pytanie na raz, a nie wszystkie.
P1
Przecież pytania mają się zmieniać za każdym razem kiedy użytkownik kliknie przycisk dalej
szatkus
Dokładnie. I za każdym razem chcesz dostać tylko jedno pytanie z listy.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)