GPUs Comparison Source Code

Browse the implementation files for GPUs Comparison.
routes.ts typescript
import type {
	CatalogItem,
	ComparisonCategory
} from '@tool.io/tools/compare';

export const comparePairSeparator = '-vs-';
export const maximumComparisonItems = 12;

export const comparisonNameSlug = (value: string) =>
	value
		.normalize('NFKD')
		.replace(/[\u0300-\u036f]/g, '')
		.toLocaleLowerCase('en-US')
		.replace(/&/g, ' and ')
		.replace(/[^a-z0-9]+/g, '-')
		.replace(/^-|-$/g, '')
		.replace(/-(\d+)-(kb|mb|gb|tb)(?=-|$)/g, '-$1$2')
		.replace(/(^|-)vs(?=-|$)/g, '$1versus');

export const parseComparisonSlugs = (
	value: string
): readonly string[] | null => {
	const parts = value.split(comparePairSeparator);
	return parts.length >= 2 &&
		parts.length <= maximumComparisonItems &&
		parts.every(Boolean)
		? parts
		: null;
};

const categoryDepth = (
	category: ComparisonCategory,
	categoriesById: ReadonlyMap<string, ComparisonCategory>
) => {
	let depth = 0;
	let current: ComparisonCategory | undefined = category;
	const visited = new Set<string>();
	while (current) {
		if (!current.parentId || visited.has(current.id)) break;
		visited.add(current.id);
		current = categoriesById.get(current.parentId);
		if (current) depth += 1;
	}
	return depth;
};

export const qualifiedComparisonSlug = (
	item: CatalogItem,
	categories: readonly ComparisonCategory[]
) => {
	const itemSlug = comparisonNameSlug(item.name) || item.slug;
	if (item.categoryIds.includes('product')) return itemSlug;
	const categoriesById = new Map(
		categories.map(
			(category) => [category.id, category] as const
		)
	);
	const category = categories
		.filter((candidate) =>
			item.categoryIds.includes(candidate.id)
		)
		.sort(
			(first, second) =>
				categoryDepth(second, categoriesById) -
					categoryDepth(first, categoriesById) ||
				second.id.length - first.id.length
		)[0];
	if (!category || itemSlug.startsWith(`${category.id}-`)) {
		return itemSlug;
	}
	return `${category.id}-${itemSlug}`;
};

export const commonComparisonCategory = (
	items: readonly CatalogItem[],
	categories: readonly ComparisonCategory[]
) => {
	if (items.length < 2) return null;
	const categoriesById = new Map(
		categories.map(
			(category) => [category.id, category] as const
		)
	);
	return (
		categories
			.filter(
				(category) =>
					category.parentId !== null &&
					items.every((item) =>
						item.categoryIds.includes(category.id)
					)
			)
			.sort(
				(first, second) =>
					categoryDepth(second, categoriesById) -
						categoryDepth(first, categoriesById) ||
					second.id.length - first.id.length
			)[0] ?? null
	);
};

const orderedSlugs = (slugs: readonly string[]) =>
	[...slugs].sort((left, right) =>
		left.localeCompare(right, 'en-US')
	);

export const comparisonPath = (
	slugs: readonly string[],
	categorySlug?: string | null
) => {
	const ordered = orderedSlugs(slugs);
	return `/compare/${categorySlug ? `${categorySlug}/` : ''}${ordered.join(comparePairSeparator)}`;
};

export const comparisonPairPath = (
	firstSlug: string,
	secondSlug: string,
	categorySlug?: string | null
) => {
	return comparisonPath([firstSlug, secondSlug], categorySlug);
};

export const comparisonItemsHref = (
	items: readonly CatalogItem[],
	categories: readonly ComparisonCategory[],
	category?: ComparisonCategory | null
) => {
	const requestedCategory =
		category &&
		items.every((item) =>
			item.categoryIds.includes(category.id)
		)
			? category
			: null;
	const effectiveCategory =
		requestedCategory ??
		commonComparisonCategory(items, categories);
	const slugs = effectiveCategory
		? items.map(
				(item) => comparisonNameSlug(item.name) || item.slug
			)
		: items.map((item) =>
				qualifiedComparisonSlug(item, categories)
			);
	return comparisonPath(slugs, effectiveCategory?.slug ?? null);
};

export const comparisonHref = (
	first: CatalogItem,
	second: CatalogItem,
	categories: readonly ComparisonCategory[],
	category?: ComparisonCategory | null
) => {
	return comparisonItemsHref(
		[first, second],
		categories,
		category
	);
};

Description

Browse the implementation files for GPUs Comparison.

References

  1. Tool.io on GitHub
  2. Tool.io TypeScript tools library

Similar or alternative tools

Don't forget to set a bookmark for tool.io!
Privacy | Imprint | Cookies