Przypsianie kilku zmiennym wartości z tablicy

0

Jak mam tablice [1,2,3,4,5] i zmienne a,b,c,d i chciałbym zmiennej a przypisać 1, b 2, c 3 itd to jak to można zrobić nie używająć destrukturyzacji. Nie chciałbym używać czegoś czego jeszcze się nie uczyłem

2

Normalnie destrukturyzacją to rób a nie wymyślasz :P

0

Bo pisze sobie aplikacje quizu i chciałbym zrobić tak aby pojawiała sie tylko jedna odpowiedź na jednym miejscu, a u mnie powtarze w dwóch miejscach nar az. Tu jest przykład https://jsfiddle.net/gucm4hd1/

1

@piotrek1998:

Nie chciałbym używać czegoś czego jeszcze się nie uczyłem

Rozumiem, co chcesz powiedzieć. Niemniej moim zdaniem nauka programowania to dobry czas właśnie na używanie czegoś, czego nie znasz do końca. :) Co innego praca, a szczególnie umieszczanie kodu na produkcji.

Bo pisze sobie aplikacje quizu i chciałbym zrobić tak aby pojawiała sie tylko jedna odpowiedź na jednym miejscu, a u mnie powtarze w dwóch miejscach nar az. Tu jest przykład https://jsfiddle.net/gucm4hd1/

Jeśli dobrze rozumiem, to chcesz zrobić losową permutację zbioru odpowiedzi (zob. https://www.math.edu.pl/permutacje). Nie wiem co prawda, jak to będzie w Twoim kodzie wyglądać, ale ogólnie mogłoby to jakoś tak wyglądać:

const input = [1, 2, 3, 4];
const takenIndices = [];
const output = [];

for (let cur = 0; cur < input.length; ++cur) {
  let randomIndex = -1;

  do {
    randomIndex = Math.floor(Math.random() * input.length);
  } while(takenIndices.includes(randomIndex));

  takenIndices.push(randomIndex);
  output.push(input[randomIndex]);
}

console.log(output); // output zawiera te same elementy co input, ale w losowej kolejności
0

Napisałem taki kod

const answerA = document.getElementById('a');
answerA.innerHTML = answerQuiz();
const answerB = document.getElementById('b');
answerB.innerHTML = answerQuiz();
const answerC = document.getElementById('c');
answerC.innerHTML = answerQuiz();
const answerD = document.getElementById('d');
answerD.innerHTML = answerQuiz();
function answerQuiz() {
	let arr = [ 'Java', 'C', 'Python', 'JS' ];
	for (let i = 0; i < arr.length; i++) {
		var one;
		var two;
		var three;
		var four;
		if (arr[i] === 'Java') {
			one = arr[i];
		} else if (arr[i] === 'C') {
			two = arr[i];
		} else if (arr[i] === 'Python') {
			three = arr[i];
		} else {
			four = arr[i];
		}
	}
}

ale wciąż jest w wariantach odpowiedzi Java,Java,Java,Java zamiast Java,C,Python,JS. Wiem że brakuje tu słowa kluczowego return tylko pytanie gdzie żeby móc uzyskać to Java,C,Python,JS, a nie to Java,Java,Java,Java?

0

Podzieliłem teraz kod na cztery funkcje

const answerA = document.getElementById('a');
answerA.innerHTML = answerQuizA([ 'Java', 'C', 'Python', 'JS' ]);
const answerB = document.getElementById('b');
answerB.innerHTML = answerQuizB([ 'Java', 'C', 'Python', 'JS' ]);
const answerC = document.getElementById('c');
answerC.innerHTML = answerQuizC([ 'Java', 'C', 'Python', 'JS' ]);
const answerD = document.getElementById('d');
answerD.innerHTML = answerQuizD([ 'Java', 'C', 'Python', 'JS' ]);
function answerQuizA(arr) {
	let arrAnswers = arr;
	var one;
	for (let i = 0; i < arrAnswers.length; i++) {
		if (arr[i] === 'Java') {
			one = arr[i];
		}
	}
	return one;
}

function answerQuizB(arr) {
	let arrAnswers = arr;
	var two;
	for (let i = 0; i < arrAnswers.length; i++) {
		if (arr[i] === 'C') {
			two = arr[i];
		}
	}
	return two;
}

function answerQuizC(arr) {
	let arrAnswers = arr;
	var three;
	for (let i = 0; i < arrAnswers.length; i++) {
		if (arr[i] === 'Python') {
			three = arr[i];
		}
	}
	return three;
}

function answerQuizD(arr) {
	let arrAnswers = arr;
	var four;
	for (let i = 0; i < arrAnswers.length; i++) {
		if (arr[i] === 'JS') {
			four = arr[i];
		}
	}
	return four;
}

to teraz działa tylko chciałbym się dowiedzieć co byście ewentualnie tutaj zmienili albo poprawili?

5

Ale namieszałeś. Twój kod to teraz ekwiwalent tego:

const answerA = document.getElementById('a');
answerA.innerHTML = 'Java';
const answerB = document.getElementById('b');
answerB.innerHTML = 'C';
const answerC = document.getElementById('c');
answerC.innerHTML = 'Python';
const answerD = document.getElementById('d');
answerD.innerHTML = 'JS';

Tylko nadmiernie rozwleczony. Czy Ty nie chciałeś czasem zrobić tego?

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

Napisałem ten kod tak

const answerA = document.getElementById('a');
answerA.innerHTML = answersQuiz();
const answerB = document.getElementById('b');
answerB.innerHTML = answersQuiz();
const answerC = document.getElementById('c');
answerC.innerHTML = answersQuiz();
const answerD = document.getElementById('d');
answerD.innerHTML = answersQuiz();

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

ale na końcu dostaje undefined. Dlaczego?

0

Gdzie jest ta wartość undefined? Gdzie ją widzisz?

0

Nie wiem, czemu wartość ostatniej odpowiedzi była undefined, ale na pewno następujący kod powinieneś usunąć:

const answerA = document.getElementById('a');
answerA.innerHTML = answersQuiz();
const answerB = document.getElementById('b');
answerB.innerHTML = answersQuiz();
const answerC = document.getElementById('c');
answerC.innerHTML = answersQuiz();
const answerD = document.getElementById('d');
answerD.innerHTML = answersQuiz();

a zamiast niego wpisać:

answersQuiz();

Mnie teraz już się nie pokazuje undefined.

To, co Ty chciałbyś osiągnąć przez oba te kody, to to samo (one robią co innego, ale ja wiem, że Ty chcesz osiągnąć to samo). Problemem jest (być może związanym z otrzymywaną wcześniej wartością undefined), że funkcja answersQuiz nic nie zwraca. Jeśli koniecznie chciałbyś wywoływać ją 4 razy, to musiałbyś ją zmienić. Moim zdaniem nie ma to sensu, bo tak, jak wygląda teraz, jest dobrze. Tylko wystarczy ją wywoływać 1 raz.


PS Aha, jeszcze ten fragment

for (let i = 1; i < answers.length; i++) {
    var answerIndex = Math.floor(Math.random() * answers.length);
}

zamień na

const answerIndex = Math.floor(Math.random() * answers.length);
0

Ok dobra. Ale jeszcze jedna rzecz. Teraz napisałem to tak https://jsfiddle.net/agy1wx8v/2/. Tylko jest inny problem

0

OK, kod nie jest dobry, ale ważne, że działa (tj. wydaje się działać). Jaki problem?

0

@Silv: jeden problem to, że na ostatniej pozycji jest zawsze JS (gdyby wdrożył Twoją poprawkę to by działało poprawnie).

A kod obecnie działa tylko dlatego, że autor zrobił literówkę w kodzie i leci wyjątek zanim nastąpi przypisanie undefined (!!!).

0

No może to nie jest naijstotniejszy problem ale i tak chciałbym wiedzieć jak go rozwiązać. Gdy odświeżam strone to zmieniają się kolejnością odspowiedzi raz jest java, python, c, js, a raz np. c,python,java,js. Problem w tym że JS jest na ostatniej pozycji i się to nie zmienia. Jedynie to.

2

@piotrek1998: spróbuj poprawić kod dokładnie tak, jak ja Ci napisałem, i zobacz, czy to zachowanie nadal będzie występować.


PS @szatkus Rzeczywiście jest wyjątek, tak.


PS2 Tj. oczywiście Error, a nie "wyjątek". ;)

0

Dobra ok. Już działa. Dzięki wielkie wszystkim za pomoc

0

Nie sorry. Przepraszam. Jednak nie działa. Mam ten kod

const answerA = document.getElementById('a');
answerA.innerHTML = answersQuiz();
const answerB = document.getElementById('b');
answerB.innerHTML = answersQuiz();
const answerC = document.getElementById('c');
answerC.innerHTML = answersQuiz();
const answerD = document.getElementById('d');
answerD.innerHTML = answersQuiz();

function answersQuiz() {
	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);
	}
	return answerIndex;
}

i dostaje błąd Uncaught ReferenceError: answerIndex is not defined

1
  1. Usuń instrukcję return. W tej postaci funkcji nie jest potrzebna. Gdyby, jak wspomniałem, funkcję zmodyfikować, to by ta instrukcja była potrzebna, ale teraz nie jest.
  2. Usuń następujący kod:
const answerA = document.getElementById('a');
answerA.innerHTML = answersQuiz();
const answerB = document.getElementById('b');
answerB.innerHTML = answersQuiz();
const answerC = document.getElementById('c');
answerC.innerHTML = answersQuiz();
const answerD = document.getElementById('d');
answerD.innerHTML = answersQuiz();
  1. Dodaj następujący kod:
answersQuiz();
0

Ok. A gdybym chciał zostać przy poprzednim rozwiązaniu, czyli móc ją wywoływać cztery razy to co konkretnie musiałbym zmienić w ciele tej funkcji?

0

Musiałbym utworzyć pętle for dla każdego elementu z tablicy answers i zwracać go dla każdego wywołania funkcji?

1

Kod powinien wyglądać na przykład tak:

const answers = [ 'Java', 'C', 'Python', 'JS' ];

function answersQuiz() {
    const answerIndex = Math.floor(Math.random() * answers.length);
    const answer = answers[answerIndex];
    answers.splice(answerIndex, 1);
    return answer;
}

Tamte cztery wywołania funkcji answersQuiz się nie zmieniają.

Nie jest to najlepszy kod, bo generalnie złą praktyką jest modyfikowanie przez funkcję kodu spoza funkcji (tzw. "efekty uboczne"). W tym wypadku takim "efektem ubocznym" jest usuwanie elementów z tablicy answers przez funkcję answersQuiz. No ale działa. (Żeby pisać lepszy kod, moim zdaniem powinieneś najpierw zrozumieć, dlaczego ten kod działa i czemu może być uznany za nienajlepszy).


PS Zobacz na przykład tu -> https://pl.wikipedia.org/wiki/Skutek_uboczny_(informatyka)


PS2 Jak coś niejasne, to pytaj.

0

A taki kod

let answerA = document.getElementById('a');
answerA.innerHTML = answersQuiz([ 'Java', 'C', 'Python', 'JS' ]);
let answerB = document.getElementById('b');
answerB.innerHTML = answersQuiz([ 'Java', 'C', 'Python', 'JS' ]);
let answerC = document.getElementById('c');
answerC.innerHTML = answersQuiz([ 'Java', 'C', 'Python', 'JS' ]);
let answerD = document.getElementById('d');
answerD.innerHTML = answersQuiz([ 'Java', 'C', 'Python', 'JS' ]);

function answersQuiz(arrAnswersQuiz) {
	for (let i = 0; i < arrAnswersQuiz.length; i++) {
		if (arrAnswersQuiz[i] === 'Java') {
			return (answerA = arrAnswersQuiz[i]);
		} else if (arrAnswersQuiz[i] === 'C') {
			return (answerB = arrAnswersQuiz[i]);
		} else if (arrAnswersQuiz[i] === 'Python') {
			return (answerC = arrAnswersQuiz[i]);
		} else {
			return (answerD = arrAnswersQuiz[i]);
		}
	}
}

chciałbym zastosować taki kod. Tylko problemem tutaj jest to return;

0

Uważam, że ten kod się nie nada. Dlaczego?

Logika funkcji answersQuiz jest w nim mniej-więcej taka:

  1. Dla każdego elementu z tablicy `arrAnswersQuiz` wykonaj:
    1.1. Jeśli dany element tablicy to "Java", to podmień element HTML przechowywany przez zmienną `answerA` na dany element tablicy i zwróć ten element.
    1.2. Jeśli nie, to jeśli dany element to "C", to podmień element HTML przechowywany przez zmienną `answerB` na dany element tablicy i zwróć ten element.
    1.3. Jeśli nie, to jeśli dany element to "Python", to podmień element HTML przechowywany przez zmienną `answerC` na dany element tablicy i zwróć ten element.
    1.4. Jeśli nie, to podmień element HTML przechowywany przez zmienną `answerD` na dany element tablicy i zwróć ten element.

Nie widzę sensu ani potrzeby użycia pętli (jakiejkolwiek) w funkcji answersQuiz. Widzisz, to jest tak, że możesz napisać dziesięć pętli jedna w drugiej i kod będzie "coś" robić. Tak działają komputery (oraz interpretatory kodu) – dla nich każdy kod ma sens, choćby dla nas, ludzi, nie miał.

Mówiąc bardzo ogólnie, mógłbyś zastosować tu taką pętlę, tak. Jednak nie robiłaby ona nic, co by przyczyniało się do szybszego i/lub prostszego uzyskania wyniku (przynajmniej moim zdaniem). Przez użycie pętli logika kodu byłaby mniej czytelna, a w konsekwencji – po prostu na koniec sam nie wiedziałbyś, co chciałeś zrobić. OK, no dobra, może Ty jako autor wiedziałbyś. ;) Ale inni nie wiedzieliby (choćby ja). Dlatego też programiści starają się pisać kod jak najbardziej, hm, "uproszczony". (I dlatego dobrą praktyką jest korzystanie np. ze wzorców projektowych – zob. https://pl.wikipedia.org/wiki/Wzorzec_projektowy_(informatyka)).

Więc – to nie jest tak, że ten kod nie ma w ogóle sensu. Ten kod "coś" robi. Ale moim zdaniem to "coś" się nie nada u Ciebie. Powiedz może: co chcesz osiągnąć, korzystając z pętli w funkcji answersQuiz?


UPDATE W związku z komentarzem:

let answerA = document.getElementById('a');
answerA.innerHTML = "Java";
let answerB = document.getElementById('b');
answerB.innerHTML = "C";
let answerC = document.getElementById('c');
answerC.innerHTML = "Python";
let answerD = document.getElementById('d');
answerD.innerHTML = "JS";
3

Jak chcesz tablicę i losować z niej kolejne elementy bez powtórzeń, to możesz coś takiego zrobić:

const answers = [ 'Java', 'C', 'Python', 'JS' ];                                                                    
answers.sort((a,b) => Math.random() - 0.5); 
let randomAnswer;
while (randomAnswer = answers.pop()) {
    console.log(randomAnswer);
}

gdzie answers.sort to jest wywołanie specjalnej funkcji, która sortuje tablicę na podstawie funkcji porównującej.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

nasza funkcja sortująca zwróci losową liczbę od -0.5 do +0.5

Więc mamy już posortowane pytanie, możemy je wybierać po kolei za pomocą funkcji pop(), która zdejmuje ostatni element tablicy.

Przypisujemy to do zmiennej randomAnswer i możemy wykonać jakąś akcję (np. console.log, ale również choćby moglibyśmy przypisać to do tekstu labelki w HTML).

Koncepcyjnie widzę, że jest to podobne do tego sposobu opisanego przez @Silv w tym poście:
Przypsianie kilku zmiennym wartości z tablicy
tylko, że w moim kodzie od razu sortujemy wg losowego klucza.

i u mnie jest pop(), które zabiera dany element, u Silv jest splice().

0

Napisałem taki kod https://jsfiddle.net/yvud6jnp/2/. Niby to działa ale problemem jest że się powtarzam w wielu miejscach w kodzie

0

Chciałbym dodać jeszcze żeby po odświeżeniu strony te elementy losow zminiały się miejscami. Napisałem coś takiego ale nie działa https://jsfiddle.net/g1d9e742/1/

0

@piotrek1998: biorąc pod uwagę to, co chcesz zrobić, jeśli już cztery razy wywołujesz funkcję answersQuiz, to nie ma sensu używać w niej pętli. Obecnie każdej odpowiedzi jest przypisywana wartość cztery razy (razem szesnaście) – o trzy za dużo. Albo pętla, albo poczwórne wywołanie.

A powyższy kod nie działa (tj. są wartości undefined), bo próbujesz indeksować wartość NaN. A wartość NaN pojawia się, bo zapomniałeś o nawiasach w wywołaniu Math.random().

Nie chcę Cię zniechęcać do pisania własnego kodu, ale czasem – rzadko, ale bywa – warto skorzystać z cudzego rozwiązania nawet jeśli na razie nie do końca się je rozumie. :)

0

A gdybym Chciał zrobić to samo tyle że z pytaniami. To czy w takim przypadku ten kod

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

mógłby przejść tyle tylko że w przypadku pytań? Bo chciałbym za każdym razem kiedy klikne w przycisk wyślij zmienić pytanie

1

Doprecyzuj proszę, co to znaczy, że chciałbyś zmienić pytanie za każdym kliknięciem. Czy chodzi Ci o coś takiego:

  1. użytkownik wybiera odpowiedź,
  2. następnie użytkownik naciska przycisk "Wyślij",
  3. następnie użytkownikowi wyświetla się następne pytanie, które jest losowe (tj. zakładam tutaj, że masz jakąś listę pytań)?

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