Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як порахувати довжину рядка без вбудованих методів чи властивостей (length)?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Довжину рядка** можна порахувати простим проходом по символах з інкрементом лічильника, не використовуючи length і методи рядків. Є два базові варіанти: через for..of (підрахунок Unicode-кодпоінтів) і через індексацію (підрахунок UTF-16 код-юнітів). **Ключове:** обидва варіанти мають O(n) за часом і O(1) за пам'яттю.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротка відповідь Порахувати довжину рядка можна простим проходом по символах з інкрементом лічильника, не використовуючи length і методи рядків. Нижче два базові варіанти: через for..of (підрахунок Unicode-кодпоінтів) і через індексацію (підрахунок UTF-16 код-юнітів). ``` // Варіант A: за кодпоінтами (враховує surrogate pairs) function strLengthByIteration(str) { let count = 0; for (const _ of str) count++; return count; } // Варіант B: за код-юнітами (як String#length) function strLengthByIndexing(str) { let i = 0; while (true) { if (str[i] === undefined) return i; i++; } } ``` ## Детальне пояснення ### Що саме ви вважаєте «довжиною» - Код-юніти (UTF-16): відповідає поведінці String.length та індексу str[i]. Емодзі поза BMP займають 2 код-юніти. - Кодпоінти (Unicode code points): for..of коректно об'єднує surrogate pairs, рахуючи такі символи як один. - Графемні кластери (те, що користувач бачить як один символ): можуть складатися з кількох кодпоінтів (наприклад, ZWJ-послідовності й комбіновані діакритики). Для точного підрахунку потрібен алгоритм сегментації графем. ### Рішення 1) Підрахунок кодпоінтів без методів і length (переважно на співбесіді): ``` function codePointLength(str) { let n = 0; for (const _ of str) n++; return n; } ``` 2) Підрахунок код-юнітів без методів і length (суворе повторення логіки String.length): ``` function codeUnitLength(str) { let i = 0; while (true) { if (str[i] === undefined) return i; i++; } } ``` 3) Якщо потрібна довжина графемних кластерів: без зовнішніх бібліотек найпростіше скористатися стандартним API сегментації (якщо його використання допустиме): ``` function graphemeLength(str) { if (typeof Intl !== 'undefined' && Intl.Segmenter) { const seg = new Intl.Segmenter('uk', { granularity: 'grapheme' }); let count = 0; for (const _ of seg.segment(str)) count++; return count; } // Фолбек: рахуємо кодпоінти let n = 0; for (const _ of str) n++; return n; } ``` ### Перевірка й приклади ``` const samples = [ "Hello", "Привіт", "\u{1F600}", // один кодпоінт, дві код-юніти "\u{1F468}\u{1F469}\u{1F467}\u{1F466}", // сім'я: кілька кодпоінтів, один видимий символ "é", // e + комбінований наголос, два кодпоінти, один видимий символ "\u0000abc" // містить нульовий символ ]; for (const s of samples) { console.log('s =', JSON.stringify(s)); console.log('codePointLength:', codePointLength(s)); console.log('codeUnitLength :', codeUnitLength(s)); console.log('graphemeLength :', graphemeLength(s)); console.log('---'); } ``` ### Крайні випадки й нюанси - Порожній рядок: обидва базові алгоритми повернуть 0. - Нульовий символ всередині рядка: індексація безпечна, оскільки перевіряється строго на undefined, а не за truthy/falsy. - Емодзі й символи поза BMP: for..of враховує surrogate pairs і дає коректний лічильник кодпоінтів. - Комбіновані діакритики й ZWJ-послідовності: один видимий символ може складатися з кількох кодпоінтів; для цього використовуйте сегментацію графем. - Продуктивність: усі варіанти мають O(n) за часом і O(1) за пам'яттю. ### Складність Час - O(n), пам'ять - O(1), де n - довжина вхідного рядка в обраній одиниці (код-юніти/кодпоінти/графеми).Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.