Skip to content

Commit 5172665

Browse files
[10.x] Add support for Number::summarize (#49197)
* Add Number::summarize * Update comment * Make units configurable * Make end unit dynamic * Remove named arguments to be consistent with other method calls * CS fix * Fix tests * Fix tests * Fix tests * formatting * format --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 0c574d4 commit 5172665

File tree

2 files changed

+105
-11
lines changed

2 files changed

+105
-11
lines changed

src/Illuminate/Support/Number.php

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,30 +141,71 @@ public static function fileSize(int|float $bytes, int $precision = 0, ?int $maxP
141141
* @param int|null $maxPrecision
142142
* @return string
143143
*/
144-
public static function forHumans(int|float $number, int $precision = 0, ?int $maxPrecision = null)
144+
public static function abbreviate(int|float $number, int $precision = 0, ?int $maxPrecision = null)
145145
{
146-
$units = [
147-
3 => 'thousand',
148-
6 => 'million',
149-
9 => 'billion',
150-
12 => 'trillion',
151-
15 => 'quadrillion',
152-
];
146+
return static::forHumans($number, $precision, $maxPrecision, abbreviate: true);
147+
}
148+
149+
/**
150+
* Convert the number to its human readable equivalent.
151+
*
152+
* @param int $number
153+
* @param int $precision
154+
* @param int|null $maxPrecision
155+
* @return string
156+
*/
157+
public static function forHumans(int|float $number, int $precision = 0, ?int $maxPrecision = null, bool $abbreviate = false)
158+
{
159+
return static::summarize($number, $precision, $maxPrecision, $abbreviate ? [
160+
3 => 'K',
161+
6 => 'M',
162+
9 => 'B',
163+
12 => 'T',
164+
15 => 'Q',
165+
] : [
166+
3 => ' thousand',
167+
6 => ' million',
168+
9 => ' billion',
169+
12 => ' trillion',
170+
15 => ' quadrillion',
171+
]);
172+
}
173+
174+
/**
175+
* Convert the number to its human readable equivalent.
176+
*
177+
* @param int $number
178+
* @param int $precision
179+
* @param int|null $maxPrecision
180+
* @param array $units
181+
* @return string
182+
*/
183+
protected static function summarize(int|float $number, int $precision = 0, ?int $maxPrecision = null, array $units = [])
184+
{
185+
if (empty($units)) {
186+
$units = [
187+
3 => 'K',
188+
6 => 'M',
189+
9 => 'B',
190+
12 => 'T',
191+
15 => 'Q',
192+
];
193+
}
153194

154195
switch (true) {
155196
case $number === 0:
156197
return '0';
157198
case $number < 0:
158-
return sprintf('-%s', static::forHumans(abs($number), $precision, $maxPrecision));
199+
return sprintf('-%s', static::summarize(abs($number), $precision, $maxPrecision, $units));
159200
case $number >= 1e15:
160-
return sprintf('%s quadrillion', static::forHumans($number / 1e15, $precision, $maxPrecision));
201+
return sprintf('%s'.end($units), static::summarize($number / 1e15, $precision, $maxPrecision, $units));
161202
}
162203

163204
$numberExponent = floor(log10($number));
164205
$displayExponent = $numberExponent - ($numberExponent % 3);
165206
$number /= pow(10, $displayExponent);
166207

167-
return trim(sprintf('%s %s', static::format($number, $precision, $maxPrecision), $units[$displayExponent] ?? ''));
208+
return trim(sprintf('%s%s', static::format($number, $precision, $maxPrecision), $units[$displayExponent] ?? ''));
168209
}
169210

170211
/**

tests/Support/SupportNumberTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,59 @@ public function testToHuman()
208208
$this->assertSame('-1 thousand quadrillion', Number::forHumans(-1000000000000000000));
209209
}
210210

211+
public function testSummarize()
212+
{
213+
$this->assertSame('1', Number::abbreviate(1));
214+
$this->assertSame('1.00', Number::abbreviate(1, precision: 2));
215+
$this->assertSame('10', Number::abbreviate(10));
216+
$this->assertSame('100', Number::abbreviate(100));
217+
$this->assertSame('1K', Number::abbreviate(1000));
218+
$this->assertSame('1.00K', Number::abbreviate(1000, precision: 2));
219+
$this->assertSame('1K', Number::abbreviate(1000, maxPrecision: 2));
220+
$this->assertSame('1K', Number::abbreviate(1230));
221+
$this->assertSame('1.2K', Number::abbreviate(1230, maxPrecision: 1));
222+
$this->assertSame('1M', Number::abbreviate(1000000));
223+
$this->assertSame('1B', Number::abbreviate(1000000000));
224+
$this->assertSame('1T', Number::abbreviate(1000000000000));
225+
$this->assertSame('1Q', Number::abbreviate(1000000000000000));
226+
$this->assertSame('1KQ', Number::abbreviate(1000000000000000000));
227+
228+
$this->assertSame('123', Number::abbreviate(123));
229+
$this->assertSame('1K', Number::abbreviate(1234));
230+
$this->assertSame('1.23K', Number::abbreviate(1234, precision: 2));
231+
$this->assertSame('12K', Number::abbreviate(12345));
232+
$this->assertSame('1M', Number::abbreviate(1234567));
233+
$this->assertSame('1B', Number::abbreviate(1234567890));
234+
$this->assertSame('1T', Number::abbreviate(1234567890123));
235+
$this->assertSame('1.23T', Number::abbreviate(1234567890123, precision: 2));
236+
$this->assertSame('1Q', Number::abbreviate(1234567890123456));
237+
$this->assertSame('1.23KQ', Number::abbreviate(1234567890123456789, precision: 2));
238+
$this->assertSame('490K', Number::abbreviate(489939));
239+
$this->assertSame('489.9390K', Number::abbreviate(489939, precision: 4));
240+
$this->assertSame('500.00000M', Number::abbreviate(500000000, precision: 5));
241+
242+
$this->assertSame('1MQ', Number::abbreviate(1000000000000000000000));
243+
$this->assertSame('1BQ', Number::abbreviate(1000000000000000000000000));
244+
$this->assertSame('1TQ', Number::abbreviate(1000000000000000000000000000));
245+
$this->assertSame('1QQ', Number::abbreviate(1000000000000000000000000000000));
246+
$this->assertSame('1KQQ', Number::abbreviate(1000000000000000000000000000000000));
247+
248+
$this->assertSame('0', Number::abbreviate(0));
249+
$this->assertSame('-1', Number::abbreviate(-1));
250+
$this->assertSame('-1.00', Number::abbreviate(-1, precision: 2));
251+
$this->assertSame('-10', Number::abbreviate(-10));
252+
$this->assertSame('-100', Number::abbreviate(-100));
253+
$this->assertSame('-1K', Number::abbreviate(-1000));
254+
$this->assertSame('-1.23K', Number::abbreviate(-1234, precision: 2));
255+
$this->assertSame('-1.2K', Number::abbreviate(-1234, maxPrecision: 1));
256+
$this->assertSame('-1M', Number::abbreviate(-1000000));
257+
$this->assertSame('-1B', Number::abbreviate(-1000000000));
258+
$this->assertSame('-1T', Number::abbreviate(-1000000000000));
259+
$this->assertSame('-1.1T', Number::abbreviate(-1100000000000, maxPrecision: 1));
260+
$this->assertSame('-1Q', Number::abbreviate(-1000000000000000));
261+
$this->assertSame('-1KQ', Number::abbreviate(-1000000000000000000));
262+
}
263+
211264
protected function needsIntlExtension()
212265
{
213266
if (! extension_loaded('intl')) {

0 commit comments

Comments
 (0)