Adding binary search and using in add sorted for stores.

This commit is contained in:
Bradley Shellnut 2023-01-22 22:39:32 -08:00
parent 416594c756
commit 0cabb2f466
8 changed files with 56 additions and 7 deletions

View file

@ -11,6 +11,8 @@
import { addToCollection, removeFromCollection } from '$lib/util/manipulateCollection';
import { addToWishlist } from '$lib/util/manipulateWishlist';
import { browser } from '$app/environment';
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$root/lib/util/gameMapper';
export let game: GameType | SavedGameType;
export let detailed: boolean = false;
@ -29,7 +31,8 @@
if (existsInCollection) {
removeGameFromCollection();
} else {
addToCollection(game);
let index = binarySearchOnStore($collectionStore, convertToSavedGame(game), 'en');
addToCollection(game, index);
if (browser) {
localStorage.collection = JSON.stringify($collectionStore);
}

View file

@ -15,6 +15,13 @@ const state = () => {
update((store) => [...store, game]);
}
function addSorted(game: SavedGameType, index: number) {
update((store) => {
store.splice(index, 0, game);
return store;
});
}
function remove(id: string) {
update((store) => {
const newStore = store.filter((item: SavedGameType) => item.id !== id);
@ -28,7 +35,7 @@ const state = () => {
});
}
return { subscribe, set, update, add, addAll, remove, removeAll };
return { subscribe, set, update, add, addSorted, addAll, remove, removeAll };
};
export const collectionStore = state();

View file

@ -0,0 +1,25 @@
import type { SavedGameType } from "../types";
export function binarySearchOnStore(inputArray: SavedGameType[], item: SavedGameType, locale = 'en') {
const collator = Intl.Collator(locale)
let low = 0;
let high = inputArray?.length - 1;
let mid;
let comparison;
while (low <= high) {
mid = (low + high) >>> 1; /* equivalent to Math.floor((low + hight) / 2) but faster */
const midValue = inputArray[mid];
comparison = collator.compare(midValue?.name, item?.name);
if (comparison < 0) {
low = mid + 1;
} else if (comparison > 0) {
high = mid - 1;
} else {
return mid;
}
}
return low;
}

View file

@ -4,11 +4,15 @@ import { ToastType, type GameType, type SavedGameType } from '$lib/types';
import { convertToSavedGame } from './gameMapper';
import { saved_game_schema } from '../zodValidation';
export function addToCollection(game: GameType | SavedGameType) {
export function addToCollection(game: GameType | SavedGameType, index: number) {
try {
console.log(`Saving game: ${JSON.stringify(game)}`);
saved_game_schema.parse(game);
collectionStore.add(convertToSavedGame(game));
if (index === -1) {
collectionStore.add(convertToSavedGame(game));
} else {
collectionStore.addSorted(convertToSavedGame(game), index);
}
toast.send('Added to collection', { duration: 3000, type: ToastType.INFO });
} catch (error) {
console.log(error);

View file

@ -34,11 +34,14 @@
$: isOpen = $boredState?.dialog?.isOpen;
if (browser) {
const collator = new Intl.Collator('en');
let collectionEmpty = $collectionStore.length === 0 || false;
let wishlistEmpty = $wishlistStore.length === 0 || false;
if (wishlistEmpty && localStorage?.wishlist && localStorage?.wishlist?.length !== 0) {
const wishlist: SavedGameType[] = JSON.parse(localStorage.wishlist);
if (wishlist?.length !== 0) {
wishlist.sort((a, b) => collator.compare(a.name, b.name));
for (const item of wishlist) {
if (!item?.searchTerms) {
item.searchTerms = `${item?.name?.toLowerCase()}`;
@ -53,6 +56,7 @@
if (collectionEmpty && localStorage?.collection && localStorage?.collection?.length !== 0) {
const collection: SavedGameType[] = JSON.parse(localStorage.collection);
if (collection?.length !== 0) {
collection.sort((a, b) => collator.compare(a.name, b.name));
for (const item of collection) {
if (!item?.searchTerms) {
item.searchTerms = `${item?.name?.toLowerCase()}`;

View file

@ -1,3 +1,5 @@
import type { PageServerLoad } from "../$types";
export const load: PageServerLoad = async ({ fetch, url }) => {
const searchParams = Object.fromEntries(url?.searchParams);
const q = searchParams?.q;

View file

@ -27,7 +27,7 @@
});
$: skip = (page - 1) * pageSize;
$: gamesShown = $searchStore.filtered.slice(skip, skip + pageSize);
$: gamesShown = $searchStore.data.slice(skip, skip + pageSize);
$: totalItems = $searchStore.search === '' ? $collectionStore.length : $searchStore.filtered.length;
interface RemoveGameEvent extends Event {

View file

@ -23,6 +23,8 @@
import LinkWithIcon from '$root/lib/components/LinkWithIcon.svelte';
import { addToWishlist } from '$root/lib/util/manipulateWishlist';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$root/lib/util/gameMapper';
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
$: existsInWishlist = $wishlistStore.find((item: SavedGameType) => item.id === game.id);
@ -41,11 +43,13 @@
firstParagraphEnd = game?.description?.indexOf('</ p>') + 5;
}
function onCollectionClick() {
function onCollectionClick() {
if (existsInCollection) {
removeFromCollection();
} else {
addToCollection(game);
let index = binarySearchOnStore($collectionStore, convertToSavedGame(game), 'en');
console.log(`Binary index: ${index}`)
addToCollection(game, index);
if (browser) {
localStorage.collection = JSON.stringify($collectionStore);
}