TypedArray oraz podmiana wysłanej wartości w tablicy dwuwymiarowej

0

Mam spory problem z ćwiczeniem. Miałem stworzyć macierz dwuwymiarową na podstawie klasy i dodać do niej kilka metod.

  1. Pierwszy problem jest taki, że wektory wiersza mam przygotować za pomocą ,,TypedArray" (dokładny cytat: ,,Wykorzystaj zwykłą tablicę (Array) do przechowania wektorów wiersza. Wektory wiersza przygotuj przy pomocy TypedArray." TypedArray odnosi się do danych binarnych, które jeszcze kiepsko rozumiem, nie do końca też rozumiem o jakie wektory chodzi - więc jak na razie tablicę stworzyłem taką, jaką potrafiłem...
  2. Drugi problem, na który natrafiłem, to problem z definiowaniem przesyłanych do metody zmiennych. Próbowałem na różne sposoby, bezskutecznie.
    (Dopóki zmieniam wartość w danej komórce jeszcze w konstruktorze - działa).
    Dokładna treść tego fragmentu zadania to: ,,Konstruktor klasy powinien przyjmować zadany rozmiar x, y. Domyślna wartość wewnątrz macierzy powinna wynosić 0. Dopisz do klasy metodę setValue z trzema parametrami x, y, value, która będzie służyła do przypisywania wartość w zadanym rzędzie i kolumnie."

Poniżej zamieszczam kod, który mam na chwilę obecną.

<!DOCTYPE html>
<html>

<head>
    <title>Tablica dwuwymiarowa</title>
    <meta charset="UTF-8"> </head>

<body>
    <p id="screen"></p>
    <script>
    class Macierz{
            constructor (x,y){
                this.x=x;
                this.y=y;
                var onScreen = '';
                let table =[];

   
                for (var i = 0; i < x; i++) {
            table[i] = [];
        }

                for (var i = 0; i < x; i++) {
            for (var j = 0; j < y; j++) {
                table[i][j] = 0,0;

            }}
  
            table[2][2]=5;
        
            for (var i = 0; i < x; i++) {
            for (var j = 0; j < y; j++) {
                onScreen += table[i][j] + " | ";
            }
            onScreen += '<br>';
        }
        document.getElementById("screen").innerHTML = onScreen;

            }
               setValue(value,x,y){
                this.x=x;
                this.y=y;
                this.table[x][y]=value;
               }
        }


        const m = new Macierz(13,7);
        m.setValue(4,2,2);

    </script>
</body>

</html>
2

TypedArray odnosi się do danych binarnych, które jeszcze kiepsko rozumiem, nie do końca też rozumiem o jakie wektory chodzi - więc jak na razie tablicę stworzyłem taką, jaką potrafiłem...

tak w skrócie to typed arrays to takie specjalne tablice w JS, w których możesz definiować wprost typ danych liczbowych (np. Float32Array to tablica, która zawiera 32-bitowe liczby zmiennoprzecinkowe, Uint8Array to tablica, która zawiera 8 bitowe liczby całkowite bez znaku itp.). Dzięki takim tablicom można łatwo pracować na danych binarnych (np. żeby komunikować się z kartą graficzną w WebGL).

Tylko, że tych tablic używa się podobnie jak zwykłych tablic, tyle, że są bardziej ograniczone (ale z drugiej strony mają fajne opcje do pracy z buforami).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays

,,TypedArray" (dokładny cytat: ,,Wykorzystaj zwykłą tablicę (Array) do przechowania wektorów wiersza.

Ja to rozumiem tak, że struktura danych, którą masz zrobić, ma wyglądać mniej więcej tak:

[
  new Float32Array(4),
  new Float32Array(4),
  new Float32Array(4),
  new Float32Array(4),
]

czyli zwykła tablica zawierająca typed arrays.

Tylko, że w praktyce robi się inaczej i zamiast wielowymiarowej tablicy robi się jednowymiarową tablicę:
new Float32Array(16)
i trzyma się w niej dane pokolei (rząd za rzędem, albo kolumna za kolumną), bo tak łatwiej później operować na danych (np. wysyłając razem do karty graficznej w WebGL, który jest częstym przypadkiem użycia takich tablic).

1

Kilka rzeczy:

  • x i y w konstruktorze i metodzie setValue to nie to samo! W kostruktorze to rozmiar macierzy, w metodzie to współrzędne - nie nadpisuj tych wartości,
  • nie mieszaj logiki macierzy z jej prezentacją - jeśli masz ją wyświetlić jako tabele to zrób sobie osobną klasę / funkcję - ostatecznie zrób chociaż osobną metodę typu draw(),
  • TypedArrays są domyślnie wypełniane zerami.

Ja bym to zrobił tak:

class Matrix {
  #data
  #width
  #height
  
  constructor(x, y) {
    this.#width = x
    this.#height = y
    this.#data = Array.from({length: y}, _ => new Uint32Array(x))
  }
  
  setValue(x, y, value){
    this.#data[y][x] = value;
  }
  
  getValue(x, y) {
    return this.#data[y][x]
  }
  
  get width() {
    return this.#width
  }
  
  get height() {
    return this.#height
  }
}

const matrix = new Matrix(5, 5)

matrix.setValue(2, 3, 9)

console.log(matrix.getValue(2, 3))
console.log(matrix.width)
console.log(matrix.height)

Minimalna implementacja (bez pól prywatnych i gettera co trochę mija się z celem, ale może o takie minimum chodzi):

class Matrix {
  constructor(x, y) {
    this.width = x
    this.height = y
    this.data = Array.from({length: y}, _ => new Uint32Array(x))
  }
  
  setValue(x, y, value){
    this.data[y][x] = value;
  }
}

const matrix = new Matrix(5, 5)

matrix.setValue(2, 3, 9)

console.log(matrix.data[3][2])
console.log(matrix.width)
console.log(matrix.height)

Oczywiście konkretny typ TypedArray dobierz wegług potrzeb.

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