Number Sorter
Il Progetto
Number Sorter interattivo sviluppato con JavaScript, focalizzato sull'implementazione e la comprensione degli algoritmi di ordinamento di base: Bubble Sort, Selection Sort, e Insertion Sort. Un progetto che svela la logica dietro l'ordinamento di una serie di numeri.
Codice Sorgente
- index.html
- styles.css
- script.js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="./styles.css" />
<title>Number Sorter</title>
</head>
<body>
<main>
<h1>Number Sorter</h1>
<form id="form" class="form">
<h2>Input:</h2>
<fieldset>
<span class="bracket">[</span>
<div>
<select
name="values"
class="values-dropdown"
aria-label="first number"
>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8" selected>8</option>
<option value="9">9</option>
</select>
<span class="comma">,</span>
</div>
<div>
<select
name="values"
class="values-dropdown"
aria-label="second number"
>
<option value="0">0</option>
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
<span class="comma">,</span>
</div>
<div>
<select
name="values"
class="values-dropdown"
aria-label="third number"
>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4" selected>4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
<span class="comma">,</span>
</div>
<div>
<select
name="values"
class="values-dropdown"
aria-label="fourth number"
>
<option value="0">0</option>
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
<span class="comma">,</span>
</div>
<div>
<select
name="values"
class="values-dropdown"
aria-label="fifth number"
>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected>3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</div>
<span class="bracket">]</span>
</fieldset>
<button id="sort">Sort</button>
</form>
<div class="output-container">
<h2>Output:</h2>
<div class="output-array">
<span class="bracket">[</span>
<div>
<span class="output-value" id="output-value-0">0</span>
<span class="comma">,</span>
</div>
<div>
<span class="output-value" id="output-value-1">0</span>
<span class="comma">,</span>
</div>
<div>
<span class="output-value" id="output-value-2">0</span>
<span class="comma">,</span>
</div>
<div>
<span class="output-value" id="output-value-3">0</span>
<span class="comma">,</span>
</div>
<div>
<span class="output-value" id="output-value-4">0</span>
</div>
<span class="bracket">]</span>
</div>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
:root {
--gray-00: #ffffff;
--gray-05: #f5f6f7;
--gray-15: #d0d0d5;
--gray-75: #3b3b4f;
--gray-85: #1b1b32;
--gray-90: #0a0a23;
--blue-50: #198eee;
--error: #a94442;
--danger-color: #850000;
--danger-background: #ffadad;
}
*,
::before,
::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Lato", Helvetica, Arial, sans-serif;
font-size: 18px;
background-color: var(--gray-85);
color: var(--gray-05);
}
main {
display: flex;
flex-direction: column;
align-items: center;
}
h1 {
margin: 30px auto;
}
h2 {
margin-bottom: 15px;
}
form {
width: 100%;
text-align: center;
padding: 15px;
}
fieldset {
border: 0 none;
height: 100%;
margin: auto;
display: flex;
justify-content: space-around;
align-items: center;
}
fieldset div {
display: flex;
justify-content: center;
align-items: center;
}
.bracket,
.comma {
font-size: 2.3em;
}
form .comma {
margin-left: 2px;
}
select {
font-family: inherit;
font-size: inherit;
line-height: inherit;
height: 38px;
width: 50px;
text-align: center;
}
button {
cursor: pointer;
margin-top: 15px;
text-decoration: none;
background-image: linear-gradient(#fecc4c, #ffac33);
border: 3px solid #feac32;
padding: 10px 16px;
font-size: 23px;
width: 100%;
}
select:focus-visible,
button:focus-visible {
outline: 3px solid var(--blue-50);
}
.output-container {
width: 95%;
min-height: 55px;
margin-top: 25px;
border-radius: 0;
padding: 15px;
overflow-wrap: break-word;
text-align: center;
}
.output-array {
width: 100%;
margin: auto;
display: flex;
align-items: center;
justify-content: space-around;
}
.output-value {
font-size: 2em;
}
.alert {
background-color: var(--danger-background);
border: 3px solid var(--danger-color);
color: var(--danger-color);
}
@media (min-width: 550px) {
form,
.output-container {
max-width: 480px;
}
fieldset {
max-width: 400px;
}
.output-array {
max-width: 420px;
}
}
const sortButton = document.getElementById("sort");
const sortInputArray = (event) => {
event.preventDefault();
const inputValues = [
...document.getElementsByClassName("values-dropdown")
].map((dropdown) => Number(dropdown.value));
const sortedValues = inputValues.sort((a, b) => {
return a - b;
});
updateUI(sortedValues);
}
const updateUI = (array = []) => {
array.forEach((num, i) => {
const outputValueNode = document.getElementById(`output-value-${i}`);
outputValueNode.innerText = num;
})
}
const bubbleSort = (array) => {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
const temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
const selectionSort = (array) => {
for (let i = 0; i < array.length; i++) {
let minIndex = i;
for (let j = i + 1; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
const temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
return array;
}
const insertionSort = (array) => {
for (let i = 1; i < array.length; i++) {
const currValue = array[i];
let j = i - 1;
while (j >= 0 && array[j] > currValue) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = currValue;
}
return array;
}
sortButton.addEventListener("click", sortInputArray);
L'Apprendimento dietro la Banalità
In progetti come questo mi rendo conto di quanto diamo tutto per scontato.
Quel che sembra un banalissimo programma che ordina 5 numeri, dal più piccolo al più grande viene visto da qualsiasi outsider con gli occhiali dell'Effetto Dunning-Kruger.
Non è stato semplice ma ha rafforzato nettamente la mia comprensione dei cicli for, specialmente quelli annidati.
Cosa Ho Imparato
Algorithmic Thinking di Base:
- Bubble Sort: Implementazione di un ciclo
forannidato per confrontare e scambiare elementi adiacenti, facendo "galleggiare" il valore più grande verso la fine dell'array a ogni iterazione. - Selection Sort: Utilizzo di un ciclo
forannidato per trovare l'indice del valore minimo nell'array non ordinato e scambiarlo con il primo elemento, restringendo progressivamente la porzione da ordinare. - Insertion Sort: Creazione di un array ordinato virtuale all'inizio, iterando attraverso l'array e inserendo ogni elemento nella sua posizione corretta all'interno della porzione già ordinata.
Cicli for Annidati:
- Comprensione profonda di come i cicli interni ed esterni interagiscono per iterare e manipolare i dati in un array.
- Utilizzo di variabili temporanee (
temp) per lo scambio di valori durante l'ordinamento.
Manipolazione del DOM:
- Selezione di una collezione di elementi con
getElementsByClassName. - Utilizzo dello spread operator (
...) per convertire unaHTMLCollectionin un array, rendendola iterabile con metodi come.map(). - Estrazione di valori da elementi
<select>con.map((dropdown) => Number(dropdown.value)). - Aggiornamento dinamico della UI con
forEachper visualizzare l'array ordinato.
Funzioni e Eventi:
- Funzione di callback per il metodo
.sort()per definire un ordinamento numerico ascendente ((a, b) => a - b). - Gestione dell'evento
clickper avviare il processo di ordinamento. - Utilizzo di
event.preventDefault()per prevenire il comportamento predefinito del form.
Prossimo Progetto: Imparare gli Advanced Array Methods costruendo una Calcolatrice Statistica