Skip to main content

Ordinal Suffix Management

The ordinal suffix utilities help you add or remove Persian ordinal suffixes (ام، م، ین) from numbers to create ordinal numbers like “اول”، “دوم”، “سوم”.

Available Functions

Add Ordinal

addOrdinalSuffix() - Add ordinal suffixes

Remove Ordinal

removeOrdinalSuffix() - Remove ordinal suffixes

Basic Usage

import { addOrdinalSuffix, removeOrdinalSuffix } from '@persian-tools/persian-tools';

Adding Ordinal Suffixes

Convert cardinal numbers to ordinal numbers in Persian:
addOrdinalSuffix("یک"); // 'اول'
addOrdinalSuffix("دو"); // 'دوم'
addOrdinalSuffix("سه"); // 'سوم'
addOrdinalSuffix("چهار"); // 'چهارم'
addOrdinalSuffix("بیست"); // 'بیستم'

Numbers with Complex Forms

addOrdinalSuffix("دوازده"); // 'دوازدهم'
addOrdinalSuffix("سی"); // 'سی‌ام'
addOrdinalSuffix("یکصد"); // 'یکصدم'
addOrdinalSuffix("هزار"); // 'هزارم'

Compound Numbers

addOrdinalSuffix("بیست و یک"); // 'بیست و یکم'
addOrdinalSuffix("سی و سه"); // 'سی و سوم'
addOrdinalSuffix("یکصد و پنج"); // 'یکصد و پنجم'

Removing Ordinal Suffixes

Convert ordinal numbers back to cardinal numbers:
removeOrdinalSuffix("اول"); // 'یک'
removeOrdinalSuffix("دوم"); // 'دو'
removeOrdinalSuffix("سوم"); // 'سه'
removeOrdinalSuffix("چهارم"); // 'چهار'
removeOrdinalSuffix("بیستم"); // 'بیست'

Complex Ordinals

removeOrdinalSuffix("دوازدهم"); // 'دوازده'
removeOrdinalSuffix("سی‌ام"); // 'سی'
removeOrdinalSuffix("یکصدم"); // 'یکصد'
removeOrdinalSuffix("بیست و یکم"); // 'بیست و یک'

Special Cases and Rules

Irregular Forms

// Special transformations
addOrdinalSuffix("یک"); // 'اول' (not 'یکم')
addOrdinalSuffix("دو"); // 'دوم' (special form)
addOrdinalSuffix("سه"); // 'سوم' (special form)

removeOrdinalSuffix("اول"); // 'یک'
removeOrdinalSuffix("دوم"); // 'دو'
removeOrdinalSuffix("سوم"); // 'سه'

Half-Space Handling

// Handles half-spaces correctly
addOrdinalSuffix("سی"); // 'سی‌ام'
addOrdinalSuffix("چهل"); // 'چهلم'
removeOrdinalSuffix("سی‌ام"); // 'سی'
removeOrdinalSuffix("چهلم"); // 'چهل'

Advanced Examples

Date Processing

function formatOrdinalDate(day: string, month: string, year: string) {
	const ordinalDay = addOrdinalSuffix(day);
	return `${ordinalDay} ${month} ${year}`;
}

formatOrdinalDate("یک", "فروردین", "۱۴۰۳"); // 'اول فروردین ۱۴۰۳'
formatOrdinalDate("بیست و یک", "مهر", "۱۴۰۲"); // 'بیست و یکم مهر ۱۴۰۲'

List Generation

function createOrderedList(items: string[]) {
	return items.map((item, index) => {
		const number = numberToWords(index + 1);
		const ordinal = addOrdinalSuffix(number);
		return `${ordinal}: ${item}`;
	});
}

const list = createOrderedList(["آیتم اول", "آیتم دوم", "آیتم سوم"]);
// ['اول: آیتم اول', 'دوم: آیتم دوم', 'سوم: آیتم سوم']

Text Processing

function processOrdinalText(text: string, direction: "add" | "remove") {
	const words = text.split(" ");

	return words
		.map((word) => {
			if (direction === "add") {
				// Try to add ordinal suffix
				const ordinal = addOrdinalSuffix(word);
				return ordinal !== word ? ordinal : word;
			} else {
				// Try to remove ordinal suffix
				const cardinal = removeOrdinalSuffix(word);
				return cardinal !== word ? cardinal : word;
			}
		})
		.join(" ");
}

Edge Cases

Invalid Input

addOrdinalSuffix(""); // ''
addOrdinalSuffix("نامعلوم"); // 'نامعلوم' (unchanged)
addOrdinalSuffix(null); // ''

removeOrdinalSuffix(""); // ''
removeOrdinalSuffix("یک"); // 'یک' (unchanged, not ordinal)
removeOrdinalSuffix(null); // ''

Already Processed

// Adding ordinal to already ordinal number
addOrdinalSuffix("اول"); // 'اول' (no change)
addOrdinalSuffix("دوم"); // 'دوم' (no change)

// Removing from cardinal number
removeOrdinalSuffix("یک"); // 'یک' (no change)
removeOrdinalSuffix("دو"); // 'دو' (no change)

Complete Ordinal Reference

  • 1-20
  • Tens
  • Hundreds & Thousands
CardinalOrdinal
یکاول
دودوم
سهسوم
چهارچهارم
پنجپنجم
ششششم
هفتهفتم
هشتهشتم
نهنهم
دهدهم
یازدهیازدهم
دوازدهدوازدهم
سیزدهسیزدهم
چهاردهچهاردهم
پانزدهپانزدهم
شانزدهشانزدهم
هفدههفدهم
هجدههجدهم
نوزدهنوزدهم
بیستبیستم

TypeScript Support

import { addOrdinalSuffix, removeOrdinalSuffix } from "persian-tools";

// Type-safe usage
const ordinal: string = addOrdinalSuffix("یک"); // 'اول'
const cardinal: string = removeOrdinalSuffix("اول"); // 'یک'

// Function typing
type OrdinalConverter = (input: string) => string;

const toOrdinal: OrdinalConverter = addOrdinalSuffix;
const toCardinal: OrdinalConverter = removeOrdinalSuffix;

Performance Considerations

  • Simple words: ~0.1ms
  • Compound numbers: ~0.2ms
  • Batch processing: Linear scaling
  • Memory usage: Minimal overhead
  • Cache results for frequently used numbers
  • Process in batches for large datasets
  • Use with number-to-words for complete pipeline

Integration Examples

Form Processing

interface DateForm {
	day: string;
	month: string;
	year: string;
}

function formatFormDate(form: DateForm): string {
	const dayNumber = wordsToNumber(form.day);
	const dayWords = numberToWords(dayNumber);
	const ordinalDay = addOrdinalSuffix(dayWords);

	return `${ordinalDay} ${form.month} ${form.year}`;
}

Content Generation

function generateRankingList(items: Array<{ name: string; score: number }>) {
	const sorted = items.sort((a, b) => b.score - a.score);

	return sorted.map((item, index) => {
		const position = numberToWords(index + 1);
		const ordinalPosition = addOrdinalSuffix(position);

		return `${ordinalPosition}: ${item.name} (${item.score} امتیاز)`;
	});
}

Text Analysis

function analyzeOrdinalUsage(text: string) {
	const words = text.split(/\s+/);
	const ordinals: string[] = [];
	const cardinals: string[] = [];

	words.forEach((word) => {
		const asCardinal = removeOrdinalSuffix(word);
		if (asCardinal !== word) {
			ordinals.push(word);
		} else {
			const asOrdinal = addOrdinalSuffix(word);
			if (asOrdinal !== word) {
				cardinals.push(word);
			}
		}
	});

	return { ordinals, cardinals };
}