IEEE.org     |     IEEE Xplore Digital Library     |     IEEE Standards     |     IEEE Spectrum     |     More Sites

Commit 1c147bfa authored by Amy Rose's avatar Amy Rose
Browse files

implement search ordering for projects grid

parent 1dc2cbd5
Pipeline #804 passed with stage
in 3 minutes and 25 seconds
---
layout: project
name: Foo
tldr: A Foo for your Bar
owner: Asdf
name: Sound Voltex
tldr: A 6-key + 2-knob game about applying effects to music
owner: dj TAKA
mystic-pid: a
---
......
---
layout: project
name: Foo2
tldr: A Foo2 for your Bar2
owner: Asdf2
name: beatmania IIDX
tldr: The genre-defining 7-key + turntable game
owner: L.E.D.
mystic-pid: b
---
......
---
layout: project
name: Foo3
tldr: A Foo3 for your Bar3
owner: Asdf3
name: pop'n music
tldr: The deceptively difficult 9-button color burger-smashing game
owner: wac
mystic-pid: c
---
......
---
layout: project
name: Foo4
tldr: A Foo4 for your Bar4
owner: Asdf4
name: Dance Dance Revolution
tldr: The ubiquitous 4-panel dance game that swept the world
owner: NAOKI
mystic-pid: d
---
......
---
layout: project
name: Foo5
tldr: A Foo5 for your Bar5
owner: Asdf
name: jubeat
tldr: A 16-button musical whack-a-mole game on life support
owner: S-C-U
mystic-pid: e
---
......
---
layout: project
name: Foo6
tldr: A Foo6 for your Bar6
owner: Asdf
name: GuitarFreaks & DrumMania
tldr: The games that Guitar Hero ripped off
owner: Yoshihiko Koezuka
mystic-pid: h
---
......
......@@ -7,6 +7,7 @@
}
.project {
max-width: 10em; // TODO: do better
margin: 1em;
h2 {
......
/* Script to do searching and filtering for the projects-grid.html partial */
const SEARCHABLE_FIELDS = ["name", "tldr", "owner"]; // config
/* Config - Field and its search weight (scalar) */
// TODO: refine values
const SEARCHABLE_FIELDS = {
"name": 2.5,
"owner": 1.75,
"tldr": 1,
};
const PROJECTS_LIST = [];
let prev_search = "";
......@@ -13,9 +19,11 @@ function init_search() {
const project_div = document.getElementById(project_id);
project.div = project_div;
project.search_valid = true;
project.search_order = 0;
project.filter_valid = true;
project.hidden = false; // performance: avoid DOM checks
project.search_score = 0;
project.search_order = 0;
project.cur_search_order = 0; // performance: avoid DOM checks
project.hidden = false; // performance: avoid DOM checks
PROJECTS_LIST.push(project);
});
/* Enable searching */
......@@ -26,32 +34,46 @@ function init_search() {
function handle_search(event) {
/* Get the search text */
const search_text = event.target.value;
const search_text = event.target.value.trim();
/* Don't waste effort if the search is the same */
if (search_text === prev_search) {
return;
}
if (search_text === prev_search) return;
prev_search = search_text;
/* Apply search */
const searched_projects = PROJECTS_LIST.map(project => {
const searched_projects = PROJECTS_LIST.filter(project => {
project.search_valid = Object.entries(project)
.some(([field, value]) => {
if (SEARCHABLE_FIELDS.includes(field)) {
if (Object.keys(SEARCHABLE_FIELDS).includes(field)) {
return value
.toLowerCase()
.indexOf(search_text.toLowerCase()) !== -1;
}
return false
return false;
});
return project.search_valid;
});
console.log(searched_projects);
/* Apply sorting */
// TODO
Object.entries(SEARCHABLE_FIELDS)
.forEach(([search_field, weight]) => {
searched_projects.forEach(project => {
const dist = levenshtein(project[search_field], search_text);
project.search_score = dist * weight;
});
});
searched_projects.sort((a, b) => {
a.search_score - b.search_score;
});
let i = 1;
searched_projects.forEach(project => {
project.search_order = i++;
});
/* Update projects grid */
update_content();
}
function update_content() {
PROJECTS_LIST.forEach(project => {
/* Apply visibility */
if (project.search_valid && project.filter_valid) {
if (project.hidden) {
project.div.classList.remove("hidden");
......@@ -63,12 +85,43 @@ function update_content() {
project.hidden = true;
}
}
/* Apply order */
if (project.search_order !== project.cur_search_order) {
project.div.style.order = project.search_order;
project.cur_search_order = project.search_order;
}
});
}
// function projects_compare(project_a, project_b) {
//
// }
function levenshtein(a, b) {
/* Check if either string is empty/nonexistent */
if (!a || a.length === 0) return b.length;
if (!b || b.length === 0) return a.length;
/* Construct matrix */
const matrix = Array(b.length + 1).fill().map(() => (
Array(a.length + 1).fill(0)
));
/* Set initial matrix values */
for (let i = 0; i <= a.length; i++) {
matrix[0][i] = i;
}
for (let j = 0; j <= b.length; j++) {
matrix[j][0] = j;
}
/* Inscrutable algorithmic absurdity */
for (let j = 1; j <= b.length; j++) {
for (let i = 1; i <= b.length; i++) {
const s = a[i - 1] === b[j - 1] ? 0 : 1;
matrix[j][i] = Math.min(
matrix[j][i - 1] + 1,
matrix[j - 1][i] + 1,
matrix[j - 1][i - 1] + s,
);
}
}
/* Return the final calculated value */
return matrix[b.length][a.length];
}
function unhide_div(div_id) {
const div = document.getElementById(div_id);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment