مقالات

یک لیست آرایه جاوا اسکریپت


من می ترسم که وقتی می خواهید لیستی از موارد را برای یک کاربر نمایش دهید .join(', ')
فقط آن را قطع نمی کند:

console.log(['apple'].join(', ')) // apple
// looks good
console.log(['apple', 'grape'].join(', ')) // apple, grape
// nah, I want "apple and grape"
console.log(['apple', 'grape', 'pear'].join(', ')) // apple, grape, pear
// wut?

خوب، پس مهارت‌های رشته‌ای خود را امتحان کنید، می‌خواهیم؟ این کاری بود که من کردم… اما
حفظ، راه بهتری وجود دارد:

آیا شنیده اید
Intl.ListFormat?
خوب، احتمالاً می تواند هر کاری را که نیاز دارید و بیشتر انجام دهد. بیایید نگاهی بیندازیم:

const items = [
	'Sojourner',
	'Opportunity',
	'Spirit',
	'Curiosity',
	'Perseverance',
]

const formatter = new Intl.ListFormat('en', {
	style: 'long',
	type: 'conjunction',
})
console.log(formatter.format(items))
// logs: "Sojourner, Opportunity, Spirit, Curiosity, and Perseverance"

نکته جالب در مورد آن این است که از آنجایی که از آن می آید Intl استاندارد،
هزاران منطقه محلی پشتیبانی می‌شوند، بنابراین می‌توانید بین‌المللی‌سازی را «رایگان» دریافت کنید.

اولین آرگومان سازنده ListFormat، محلی است (ما استفاده می کنیم
'en' در بالا برای “انگلیسی”). آرگومان دوم گزینه های است style و
type.The style گزینه می تواند یکی از 'long'، 'short'، یا 'narrow'.The
type می تواند یکی از 'conjunction'، 'disjunction'، یا 'unit'.

با فهرست بالا، در اینجا کل ترکیب اینها آمده است (ص en مانند
محلی):

long
conjunction ساکن، فرصت، روح، کنجکاوی و پایداری
disjunction ساکن، فرصت، روح، کنجکاوی یا پشتکار
unit ساکن، فرصت، روح، کنجکاوی، پشتکار
short
conjunction مهاجر، فرصت، روحیه، کنجکاوی، و پشتکار
disjunction ساکن، فرصت، روح، کنجکاوی یا پشتکار
unit ساکن، فرصت، روح، کنجکاوی، پشتکار
narrow
conjunction ساکن، فرصت، روح، کنجکاوی، پشتکار
disjunction ساکن، فرصت، روح، کنجکاوی یا پشتکار
unit فرصت ساکن روح کنجکاوی تداوم

جالب است که اگر با منطقه بازی کنیم، همه چیز به طور غیر منتظره ای رفتار می کند:

new Intl.ListFormat('en', { style: 'narrow', type: 'unit' }).format(items)
// Sojourner Opportunity Spirit Curiosity Perseverance

new Intl.ListFormat('es', { style: 'narrow', type: 'unit' }).format(items)
// Sojourner Opportunity Spirit Curiosity Perseverance

new Intl.ListFormat('de', { style: 'narrow', type: 'unit' }).format(items)
// Sojourner, Opportunity, Spirit, Curiosity und Perseverance

شاید آلمانی‌زبان‌ها بتوانند ما را روشن کنند که چرا این ترکیب narrow و unit
برای de بیشتر شبیه long و conjunction چون هیچ نظری ندارم

یک مورد کمتر شناخته شده نیز وجود دارد localeMatcher گزینه ای که می توان برای آن پیکربندی کرد
یا 'lookup' یا 'best fit' (پیش فرض است 'best fit').تا جایی که بتوانم
از
mdn
هدف آن این است که به مرورگر بگوید که چگونه تعیین کند که از کدام منطقه استفاده کند
در سازنده داده شده است. در آزمایشات خودم نتوانستم الف را تعیین کنم
تفاوت در عملکرد هنگام جابجایی بین این گزینه ها 🤷‍♂️

راستش را بخواهید، فکر می کنم معمولاً برای مواردی از این دست بهتر است به مرورگر اعتماد کنیدبه جای نوشتن آنچه مرورگر ارائه می دهد. این به این دلیل است که هر چه مدت زمان بیشتری برای نوشتن نرم افزار صرف کنم، بیشتر متوجه می شوم که به ندرت همه چیز به سادگی ما است
من فکر می کنم آنها خواهند بود (مخصوصاً در مورد بین المللی شدن). اما آنجا
قطعا مواقعی وجود دارد که پلتفرم از کار می افتد و شما نمی توانید این کار را انجام دهید
به دنبال چه کاری هستید، پس منطقی است که خودتان آن را انجام دهید.

بنابراین من یک تابع کوچک را که به خوبی با کیس مورد استفاده من مطابقت داشت کنار هم قرار دادم و انجام دادم
من می خواهم آن را با شما به اشتراک بگذارم. قبل از اینکه این کار را انجام دهم، می خواهم روشن کنم که من من انجام دادم این را امتحان کنید
بدون کاهش (با استفاده از حلقه for) و فکر می کنم روش کاهش معنی دار بود
ساده تر در صورت تمایل نسخه حلقه for را امتحان کنید.

function listify(
	array,
	{ conjunction = 'and ', stringify = (item) => item.toString() } = {},
) {
	return array.reduce((list, item, index) => {
		if (index === 0) return stringify(item)
		if (index === array.length - 1) {
			if (index === 1) return `${list} ${conjunction}${stringify(item)}`
			else return `${list}, ${conjunction}${stringify(item)}`
		}
		return `${list}, ${stringify(item)}`
	}, '')
}

در پایگاه کد من به صورت زیر استفاده می شود:

const to = `To: ${listify(mentionedMembersNicknames)}`
// and
const didYouMean = `Did you mean ${listify(closeMatches, {
	conjunction: 'or ',
})}?`

من وقت می گذارم تا این کد را با شما مرور کنم، اما در واقع همانطور که من بودم
من در حال نوشتن این پست هستم
متوجه شدم که مورد استفاده من آنقدرها که فکر می کردم خاص نیست
بود و من سعی کردم این را بازنویسی کنم تا از آن استفاده کنم Intl.ListFormat و آیا شما نمی دانید
این، با یک تغییر کوچک API، من توانستم پیاده سازی ساده تری انجام دهم
بالاتر از استاندارد:

function listify(
	array,
	{
		type = 'conjunction',
		style = 'long',
		stringify = (item) => item.toString(),
	} = {},
) {
	const stringified = array.map((item) => stringify(item))
	const formatter = new Intl.ListFormat('en', { style, type })
	return formatter.format(stringified)
}

با آن، اکنون این کار را انجام می دهم:

// no change for the default case
const to = `To: ${listify(mentionedMembersNicknames)}`
// switch to using the "type" option rather than overloading/abusing the term "conjunction"
const didYouMean = `Did you mean ${listify(closeMatches, {
	type: 'disjunction',
})}?`

بنابراین فقط به شما نشان می دهد که شما هستید شاید برای انجام کارهای اضافی که شما
ممکن است نیازی به انجام نباشد پلتفرم احتمالاً این کار را برای شما انجام می دهد
به طور خودکار! اوه، و فقط برای سرگرمی، در اینجا یک نسخه TypeScript وجود دارد
کد تمام شده (من در حال انتقال این پروژه به TypeScript هستم).

// unfortunately TypeScript doesn't have Intl.ListFormat yet 😢
// so we'll just add it ourselves:
type ListFormatOptions = {
	type?: 'conjunction' | 'disjunction' | 'unit'
	style?: 'long' | 'short' | 'narrow'
	localeMatcher?: 'lookup' | 'best fit'
}
declare namespace Intl {
	class ListFormat {
		constructor(locale: string, options: ListFormatOptions)
		public format: (items: Arraystring>) => string
	}
}

type ListifyOptionsItemType> = {
	type?: ListFormatOptions['type']
	style?: ListFormatOptions['style']
	stringify?: (item: ItemType) => string
}
function listifyItemType>(
	array: ArrayItemType>,
	{
		type = 'conjunction',
		style = 'long',
		stringify = (thing: { toString(): string }) => thing.toString(),
	}: ListifyOptionsItemType> = {},
) {
	const stringified = array.map((item) => stringify(item))
	const formatter = new Intl.ListFormat('en', { style, type })
	return formatter.format(stringified)
}

و اکنون ما تکمیل خودکار شیرین را برای آن گزینه‌ها دریافت می‌کنیم و بررسی آن را تایپ می‌کنیم
روش stringify خوب

اوه، به هر حال، شما همیشه می خواهید پشتیبانی مرورگر را برای هر چیزی دوباره بررسی کنید
شما استفاده می کنید caniuse.com وجود دارد و
مقاله MDN در Intl.ListFormat
نیز دارد
نمودار

امیدوارم برای شما جالب و مفید بوده باشد!


Source link

نوشته های مشابه

دیدگاهتان را بنویسید

دکمه بازگشت به بالا