How Lodash pad Handles Uneven String Balancing
The _.pad method in Lodash centers a target string
within a given length by distributing padding characters across both
sides. When the difference between the target length and the string
length is odd, or when a custom padding string does not fit
symmetrically into the allocated slots, Lodash resolves these imbalances
through a deterministic two-step structural mechanism: an asymmetrical
integer split via Math.floor and Math.ceil,
followed by an internal string-slicing routine in its helper function
createPadding.
Left and Right Allocation Logic
When _.pad(string, length, chars) is invoked, Lodash
first calculates the total remaining space needed to meet the requested
target length:
var mid = (length - strLength) / 2;If mid is a floating-point number resulting from an odd
deficit, the library cannot divide the space equally. Lodash resolves
this asymmetry by prioritizing the right side:
- Left padding length:
Math.floor(mid) - Right padding length:
Math.ceil(mid)
For example, centering the three-character string 'cat'
within a target length of 6 produces a difference of
3, making mid = 1.5. Lodash allocates
Math.floor(1.5) (1 character) to the left flank and
Math.ceil(1.5) (2 characters) to the right flank, resulting
in ' cat '. The extra character always falls on the
right.
Handling
Custom Pattern Truncation with createPadding
When a multi-character sequence is passed as the chars
argument, the required flank length rarely aligns perfectly with the
pattern's length. Lodash constructs each flank independently using its
internal createPadding(length, chars) function.
The construction follows these structural steps:
- Repetition Calculation: Lodash calculates how many
times the pattern must repeat to cover the required flank length:
var repeatCount = Math.ceil(length / stringSize(chars)); var result = baseRepeat(chars, repeatCount); - Left-to-Right Truncation: Because repeating the
pattern often exceeds the exact flank length, Lodash truncates the
overflow strictly from the right using string slicing:
return hasUnicode(chars) ? castSlice(stringToArray(result), 0, length).join('') : result.slice(0, length);
Because truncation occurs strictly at index 0 through
length, the pattern is preserved from left to right on both
the left and right flanks. It does not attempt to mirror or invert the
characters on the left side.
Structural Example of Asymmetrical Padding
Consider padding the string 'abc' (length 3) to a total
length of 8 using the sequence '1234':
- Total required padding:
8 - 3 = 5 - Midpoint calculation:
5 / 2 = 2.5 - Left target length:
Math.floor(2.5) = 2 - Right target length:
Math.ceil(2.5) = 3
Next, createPadding runs for each side:
- Left side (
length = 2):'1234'repeated once is'1234'. Slicing to 2 characters yields'12'. - Right side (
length = 3):'1234'repeated once is'1234'. Slicing to 3 characters yields'123'.
Concatenating left padding, original string, and right padding yields:
_.pad('abc', 8, '1234'); // => '12abc123'Unicode and Multi-Byte Truncation Safety
When dealing with emojis, surrogate pairs, or complex Unicode
grapheme clusters, native JavaScript methods like .slice()
can split code units and produce corrupted characters. Lodash checks for
complex symbols using an internal regular expression via
hasUnicode(chars).
If Unicode symbols are detected, the truncation step bypasses
standard String.prototype.slice and converts the repeated
string into an array of full symbols via stringToArray. It
then uses castSlice on the symbol array before joining it
back into a string, ensuring that inherently uneven truncation cuts
along true character boundaries rather than raw UTF-16 code units.