Przypsianie kilku zmiennym wartości z tablicy

1

Napisałęm coś takiego

function getRandomVariants() {
	do {
		var randomQuestIndex = Math.floor(Math.random() * quizArr.length);
	} while (randomQuestIndex === randomIndex);
	randomIndex = randomQuestIndex;
	headQuestions.innerHTML = quizArr[randomQuestIndex].question;
}

ale ja raczej chciałem uzyskać coś podobnego do tej funkcji

function getRandomQuestion() {
	const headQuestions = document.getElementById('header-questions');
	do {
		var randomQuestIndex = Math.floor(Math.random() * questArr.length);
	} while (randomQuestIndex === randomIndex);
	randomIndex = randomQuestIndex;
	headQuestions.innerHTML = questArr[randomQuestIndex];
}

a nie zmienić raptem jeden element

1
let randomIndex = -1;
function getRandomVariants() {
	do {
		var randomQuestIndex = Math.floor(Math.random() * quizArr.length);
	} while (randomQuestIndex === randomIndex);
	randomIndex = randomQuestIndex;
	headQuestions.innerHTML = quizArr[randomQuestIndex].question;
}
0

Co do funkcji getRandomQuestion – ten kod:

headQuestions.innerHTML = questArr[randomQuestIndex];

wyświetla cały obiekt pytania (jeśli go wykonałeś, to widzisz). A powinieneś raczej przypisać właściwość question tego obiektu. Poza tym funkcja getRandomQuestion wygląda w miarę dobrze; może tylko nazwałbym inaczej: showQuestion (ale dalej w tym poście użyję jeszcze obecnej nazwy).

Co do funkcji getRandomVariants, powinna być wywoływana w każdym wywołaniu funkcji getRandomQuestion. Powinna być napisana inaczej – rozumiem, że to jeszcze będziesz zmieniać. Między innymi zamiast quizArr.length trzeba użyć quizArr[randomQuestIndex].answers.length.


PS Dla funkcji getRandomVariants potrzeba deklaracji podobnej do let randomIndex = -1;. Teoretycznie można umieścić ją w zasięgu globalnym, poza funkcjami, ale moim zdaniem bardziej intuicyjnie umieścić ją w funkcji getRandomQuestion. UPDATE Mój błąd – trzeba umieścić ją w funkcji getRandomQuestion, bo inaczej losowania odpowiedzi dla różnych pytań będą zależeć od siebie (a nie powinny).

1

Czyli w tej funkcji getRandomQuestion zamiast zanpisać tak headQuestions.innerHTML = questArr[randomQuestIndex]; powinienem zapisać to tak headQuestions.innerHTML = questArr[randomQuestIndex].question? Czy tak?

0

Jeśli chodzi o tą funkcje getRandomVariants to ja chce zrobić tą funckje zarówno dla pytań jak i odpowiedzi. Tylko ja na razie ją nazwałem getRandomVariants bo nie miałem pomysłu na inną nazwe. Ona nie tyczy się tylko pytań. Na razie chce ją napisać dla pytań, a jak już wszystko będzie ok to dodać do niej też pytania.

0

Nie wiem, czy tak się da, żeby tę samą funkcję dla obu rzeczy zrobić. Bo, jak napisałem, według mnie jedna funkcja powinna być wywoływana w drugiej. Ale spróbuj, zobaczymy.

0

Dobrze. Ustalmy pewne rzeczy żeby nie było nieścisłości. Co konkretnie powinna robić ta nowa funkcja. Bo wnioskuje z tego co ty mi napisałeś żeby stworzyć nową funkcje i zostawić jednocześnie te trzy

function getRandomQuestion() {
	const headQuestions = document.getElementById('header-questions');
	do {
		var randomQuestIndex = Math.floor(Math.random() * questArr.length);
	} while (randomQuestIndex === randomIndex);
	randomIndex = randomQuestIndex;
	headQuestions.innerHTML = questArr[randomQuestIndex].question;
}

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

function randomAnswersQuiz() {
	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);
	}
}

bo nie ukrywam od początku tak chciałem zrobić, a nie wrzucać wszystko do jednej funkcji. Oraz wywoływać funckje getRandomVaraints(nie zwracaj uwagi na nazwe tej funckji i tak ją potem jeszcze zmienie) w funkcji getRandomQuestion

0

Ten kod wygląda teraz tak https://jsfiddle.net/1zwerjdv/. Czy o to chodziło czy jeszcze nie do końca.

1

Wiesz co, zaczyna robić się bałagan. Moim zdaniem usuń wszystko poza tym kodem:

let randomIndex = -1;
const btnSubmit = document.querySelector('.btn-submit');
let quizArr = [
    ... // Tutaj cała tablica, już jej nie kopiowałem tutaj dla czytelności
];
function getRandomQuestion() {
    getRandomVariants();
}
function getRandomVariants() {
    // Tu puste na razie
}
btnSubmit.addEventListener('click', function() {
    // Tu puste na razie
});

I będziemy dalej zmieniać. Trzeba będzie pozmieniać nazwy, by były bardziej czytelne. Prawie cały (cały?) usunięty kod jest i tak w tym wątku zamieszczony, więc nie ma straty.

0

Spoko

0

Ok gotowe

let randomIndex = -1;

const btnSubmit = document.querySelector('.btn-submit');

let quizArr = [
	{
		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' ]
	}
];

function getRandomQuestion() {
	getRandomVariants();
}

function getRandomVariants() {}

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

od czego najpierw powinienem zacząć?

0

Wiesz staram się pisać kod w miare możliwości sam ale w związku iż jestem początkujący jestem też ciekaw twojej koncepcji na rozwiązanie danego problemu. Oczywiście nie chce żebyś podawał mi rozwiązanie na tacy ale z chęcią naucze się czegoś nowego

1

Zmieniamy nazwy:

  1. Nazwa randomIndex jest niedokładna. W tak prostym kodzie jak Twój problemu nie widać, ale warto sobie wyrobić nawyk nazywania zmiennych możliwie dokładnie (w ogólnym przypadku takie działanie zależy od kilku czynników, między innymi języka programowania). Lepiej: oldQuestionIndex. Bo ta zmienna przechowuje dokładnie to: poprzedni (= "stary") indeks pytania.
  2. Nazwa getRandomQuestion trochę przeczy logice kodu – nie tylko pobierasz pytanie, ale również je wyświetlasz. Ponownie: w taki prostym kodzie nie widać, w większym byłoby widać (np. gdyby miał 10 tys. linii). Lepiej: showRandomQuestion, albo displayRandomQuestion, albo podobnie (jeśli masz jakąś inną propozycję).

Bonus: moim zdaniem, tak bardziej kosmetycznie, warto zmienić deklarację let quizArr. Słowo kluczowe let sugeruje, że zmienna quizArr może się zmieniać (i jednocześnie na to zezwala). Nie chodzi tutaj o zawartość tablicy, tylko to, że tej zmiennej może na przykład zostać przypisana inna tablica. Ponieważ sądzę, że nie planujesz przypisywać tej zmiennej nic innego, to możesz zmienić tę deklarację na const quizArr. Słowo kluczowe const zarówno sugeruje, jak i w ogóle zabrania przypisywania tej zmiennej czegokolwiek innego. Znów: w tak prostym kodzie po prostu pamiętasz, żeby tej zmiennej nic nie przypisywać. W kodzie o 10 tys. linii będzie ciężko pamiętać o wszystkich zmiennych. Lub: gdybyś rozwijał projekt pół roku czy rok, to duża szansa, że zapomniałbyś, że danej zmiennej nie chciałeś na początku nic przypisywać.

1

Najlepiej jakbyś wziął kod z poprzedniej strony i wrzucił w osobną funkcję. Nazwij to np. putAnwsers czy jak tam chcesz, przekazuj tablicę z odpowiedziami i niech ta sobie je losowo porozrzuca po tych obiektach a, b, c, d. Wywołuj to w showRandomQuestion. W ten sposób będziesz miał w miarę działający quiz. Dorzuciłbym też pole correctAnswer do definicji pytań i na tym zbudował np. jakiś licznik punktów.

0

Ok zrobione. Co dalej?

1

Mamy dwa cele; można by je nazwać wymaganiami funkcjonalnymi. Czyli:

  1. po załadowaniu strony wyświetlić losowe pytanie;
  2. po naciśnięciu przycisku "Wyślij" wyświetlić losowe pytanie, różne od bieżącego.

Przy okazji zauważyłem pewien problem. Każde pytanie ma inne odpowiedzi. W związku z tym idea wyświetlania odpowiedzi w losowej kolejności nie ma sensu. Jak myślisz? Chyba że… chciałbyś mieć kolejność odpowiedzi dla danego wyświetlenia danego pytania różną od kolejności odpowiedzi dla poprzedniego wyświetlenia tego pytania?

Niezależnie od Twojej odpowiedzi na te pytania, już teraz możemy zacząć implementować wspomniane dwa wymagania. Umieść wywołanie funkcji showRandomQuestion (nie wiem, jaką nazwę ostatecznie nadałeś) w dwóch miejscach: (1) w handlerze kliknięcia na przycisk btnSubmit, (2) na samym końcu całego kodu.

0

Zrozumiałem zarówno pierwsze jak i drugie pytanie

0

Ok. Teraz jest ok https://jsfiddle.net/tqyovh6a/.

0

Powiedz co dalej mam zrobić. Teraz wychodze z założenia że powinienem zająć się odpowiedziami?

0

Zastanwiałem się czy aby móc losować odpowiedzi mógłbym użyć teoretycznie zagnieżdżonych pętli. Myślałem nad czymś takim https://jsfiddle.net/g58y1n0p/ żeby móc przypisywać kilku wariantom różne odpowiedzi ponieważ obecny kod powoduje coś takiego https://jsfiddle.net/ztwqvk67/1/. Oczywiście to jest tylko poglądowa wersja z tymi pętlami które napisałem ale być może dałoby się zrobić z tego jakiś użytek ponieważ obecne działanie tych pętli odbiego od tego co chciałbym uzyskać

0

Ten kod który tutaj jest

const objectName = [
	{
		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' ]
	}
];
for(let i = 0; i < objectName.length; i++){
		for(let j = 0; j < objectName[i][value].length; j++){
			console.log(objectName[i][value][j]);
	}
}

chce wykorzystać do tablic answers w obiekcie quizArr

0

@szatkus:
To jest obecny kod

function showRandomQuestions() {
	do {
		var randomQuestIndex = Math.floor(Math.random() * quizArr.length);
	} while (randomQuestIndex === oldQuestionIndex);
	oldQuestionIndex = randomQuestIndex;
	headerQuestions.innerHTML = quizArr[randomQuestIndex].question;
}
function showAnswersQuiz(answers) {
	let arrAnswerVaranty = [ 'a', 'b', 'c', 'd' ];
	for (const id in arrAnswerVaranty) {
		var displayAnswersVaranty = document.getElementById((arrAnswerVaranty[id].innerHTML = answers[id]));
	}
	return displayAnswersVaranty;
}

kod w funkcji showRandomQuestions zostaje czy go usunąć i wstawić tam wywołanie tej funkcji showAnswersQuiz z tablicą odpowiedzi?

0

Tak to miało wyglądać?


function showRandomQuestions() {
	do {
		var randomQuestIndex = Math.floor(Math.random() * quizArr.length);
	} while (randomQuestIndex === oldQuestionIndex);
	oldQuestionIndex = randomQuestIndex;
	headerQuestions.innerHTML = quizArr[randomQuestIndex].question;
	showAnswersQuiz([ 'Java', 'C', 'Python', 'JS' ]);
	showAnswersQuiz([ 'Florin Pop', 'Joe Biden', 'Ivan Saldano', 'Mihai Andrei' ]);
	showAnswersQuiz([
		'Hypertext Markup Language',
		'Cascading Style Sheet',
		'Jason Object Notation',
		'Helicopters Terminals Motorboats Lamborginis'
	]);
	showAnswersQuiz([ '1996', '1995', '1994', 'none of the above' ]);
}
function showAnswersQuiz(answers) {
	let arrAnswerVaranty = [ 'a', 'b', 'c', 'd' ];
	for (const id in arrAnswerVaranty) {
		var displayAnswersVaranty = document.getElementById((arrAnswerVaranty[id].innerHTML = answers[id]));
	}
}
0

Dostaje answers is not defined https://jsfiddle.net/esz79bxj/1/

0

Ok błędu już nie ma ale nadal nie wyświetlają się pytania https://jsfiddle.net/L3kujr7b/

1

@piotrek1998

Dobra ok. A nie mogę wykorzystać tego kodu z tymi pętlami. Nie chce od razu korzystać z metod wbudowanych —

no właśnie, jak to zrobić bez sortowania po randomie? Można by to zrobić tak, żeby budować nową tablicę losując za każdym razem indeks elementu. I teraz - żeby się elementy nie powtarzały, to zapamiętywać, które indeksy się powtórzyły. I jeśli dany wylosowany indeks nie wystąpił wcześniej, to spoko, możemy dać push dodając nowy element do naszej nowej tablicy. Jeśli jednak już wystąpił, to zwiększamy o 1 indeks elementu (jak trafimy na koniec tablicy, to lecimy od zera) i lecimy dalej w pętli, aż w końcu natrafimy na puste miejsce i dopiero tam to damy (możemy też użyć dzielenia z resztą index % arr.length, wtedy nie będziemy musieli dawać warunku czy jest koniec tablicy, to 0, bo dzielenie z resztą samo nam to zrobi.

0

@piotrek1998: przepraszam, ale jeśli chodzi o mnie, to ja jednak wrócę do kodu sprzed Twoich ostatnich modyfikacji (acz już implementującego to, co napisałem ostatnio). Nie będę brać pod uwagę ani Twojego ostatniego kodu, ani propozycji @LukeJL oraz @szatkus Inaczej pogubię się. (Jeśli wolisz ich porady, mogę się wycofać, choćby tymczasowo).

Niech naszym kodem wyjściowym będzie teraz poniższy kod:

let oldQuestionIndex = -1;

const btnSubmit = document.querySelector('.btn-submit');

const quizArr = [
    {
        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' ]
    }
];

function showRandomQuestion() {
    getRandomVariants();
}

function getRandomVariants() {}

btnSubmit.addEventListener('click', function() {
    showRandomQuestion();
});

showRandomQuestion();

Zmieniłem nazwę showRandomQuestions na showRandomQuestion w stosunku do Twojego ostatniego kodu (zauważ brak literki s na końcu).

Teraz dobrze, żebyś był pewien, jak ten kod działa:

  1. Po załadowaniu strony dzieją się następujące rzeczy (mniej-więcej w tej kolejności):
    1.1. Deklarowana jest zmienna oldQuestionIndex i przypisywana jest jej liczba -1.
    1.2. Wywoływana jest metoda querySelector obiektu document, a tym samym pobierany jest przycisk (czyli element HTML) o klasie btn-submit. Dalej: deklarowana jest zmienna btnSubmit. Na końcu pobrany przycisk jest przypisywany tej zmiennej.
    1.3. Deklarowana jest zmienna quizArr i przypisywana jest jej tablica z pytaniami.
    1.4. Deklarowana jest funkcja showRandomQuestion.
    1.5. Deklarowana jest funkcja getRandomVariants.
    1.6. Wywoływana jest metoda addEventListener przycisku btnSubmit.
    1.7. Wywoływana jest funkcja showRandomQuestion.
  2. Po wywołaniu metody addEventListener dzieją się następujące rzeczy:
    2.1. Przypisywana jest funkcja anonimowa do zdarzenia click przycisku btnSubmit.
  3. Po kliknięciu przycisku btnSubmit (czyli nadejściu jego zdarzenia click) dzieją się następujące rzeczy:
    3.1. Wywoływana jest funkcja anonimowa przypisana do tego zdarzenia, a tym samym wywoływana jest funkcja showRandomQuestion.
  4. Po wywołaniu funkcji showRandomQuestion dzieją się następujące rzeczy:
    4.1. Wywoływana jest funkcja getRandomVariants.

Powyższy opis działania jest tylko pomocniczy. Nie musisz z niego korzystać w dalszej pracy, choć dobrze, jak będziesz to działanie rozumieć.

Na razie tyle. Żeby nie wszystko naraz, napiszę ciąg dalszy jutro.


@LukeJL , @szatkus – przepraszam, że nie korzystam z Waszego kodu i propozycji.

1

Doprecyzujmy nasze cele. Przypomnę, że oryginalne były takie:

Silv napisał(a):

Mamy dwa cele; można by je nazwać wymaganiami funkcjonalnymi. Czyli:

  1. po załadowaniu strony wyświetlić losowe pytanie;
  2. po naciśnięciu przycisku "Wyślij" wyświetlić losowe pytanie, różne od bieżącego.

Poprzednio zapytałem Cię, czy chciałbyś mieć kolejność odpowiedzi dla danego wyświetlenia danego pytania różną od kolejności odpowiedzi dla poprzedniego wyświetlenia tego pytania. Nie odpowiedziałeś, ale to nic, bo obecnie myślę, że nie jest to najlepsze pytanie; wymagałoby zmiany tablicy quizArr, a tego wolę nie robić, bo za dużo pracy by było naraz. Moim zdaniem po prostu wyświetlajmy odpowiedzi w losowej kolejności. Nie ma to co prawda większego znaczenia – i tak nie będzie tego widać, bo dla każdego pytania są inne odpowiedzi. Ale zróbmy tak, żeby nie komplikować. Zgadzasz się?


PS Przepraszam, że tak to ciągnę, ale to kluczowa rzecz według mnie, a wczoraj nie pomyślałem o tym.

2

Teraz tak:

  1. Trzeba udostępnić w kodzie element HTML, w którym będzie wyświetlane pytanie. To już zrobiłeś w ostatnim swoim kodzie. Tylko więc przekleję:
const headerQuestions = document.getElementById('header-questions');

Moim zdaniem nazwa tej zmiennej i identyfikator tego elementu mogły by być inne. Obecne sugerują, że w tym nagłówku będzie kolekcja pytań, a nie jedno pytanie. Proponowałbym zarówno w identyfikatorze, jak i w nazwie zmiennej usunięcie literki s z końca (pamiętaj o zmianie identyfikatora także w kodzie HTML).

  1. Trzeba udostępnić w kodzie elementy HTML, w których będą wyświetlane odpowiedzi. To też zrobiłeś w ostatnim swoim kodzie. Przekleję:
const answerA = document.getElementById('a');
const answerB = document.getElementById('b');
const answerC = document.getElementById('c');
const answerD = document.getElementById('d');

Te zmienne i identyfikatory można by również inaczej nazwać, żeby zachować obecną konwencję, jaką widzę u Ciebie. Proponowałbym poprzedzenie nazwy każdej zmiennej ciągiem label (i oczywiście zmianę litery a na A), oraz poprzedzenie każdego identyfikatora ciągiem label- (zauważ kreskę na końcu; pamiętaj o kodzie HTML).

1

Teraz jest ok https://jsfiddle.net/3muL20rq/. Czy coś musze poprawić jeszcze?

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