• {{::namespace.name}}
Type Name Module
All Default Bookmarked
You are looking at a previous docs version. Live examples are disabled.

You are looking at a previous docs version. Sections below this point may not apply.

Method Types

Sugar has 5 basic method types.

Icon Type Description
S Static Static methods are called directly on their namespace: either the global namespace (when extending or using polyfills) or the Sugar namespace (i.e. `Sugar.Array`).
I Instance Instance methods are called directly on objects when extending, using polyfills, or chainables. They can also be called statically on the Sugar namespace, taking the object as their first argument.
R Range Range methods are instance methods called on range objects. [See more](#/Ranges).
A Accessor Accessors are static methods that provide a way to set internal options. [See more](#/Accessors).
G N Core Core methods provide core Sugar functionality. "Global" methods are called on the Sugar global itself, while "Namespace" methods are called on a Sugar namespace.
In extended mode, only static and instance methods are mapped to native objects. Range methods are called directly on [ranges](#/Ranges), while accessor and core methods are called on the Sugar global.

Modules

Although Sugar builds can now be customized at method level, modules are still used as an intuitive way of grouping similar methods. The main sugar npm package is organized into modules, which can be required together. Non-default modules are also excluded from the main Sugar build, but can be added by creating a customized build. Likewise, non-default modules (with the exception of ES5 as noted below) are not included in the sugar npm package, however can be included individually (i.e. sugar-language, etc).

Note that in the sugar npm package, ES5 polyfills are included, however must be explicitly required. Additionally, two builds are included in the dist/ directory, one with ES5 polyfills, and one without.

Icon Name Default Description
Core Core functionality including the ability to define methods and extend onto natives.
Array Array manipulation and traversal, alphanumeric sorting, collation, and more.
Date Date parsing, formatting, relative formats, locale support, and more.
Enumerable Counting, mapping, and finding methods on both arrays and objects.
ES5 Full ES5 polyfill suite for older browsers such as IE8 and below.
ES6 Basic ES6 polyfills for Sugar methods. Can be removed if ES6 is supported.
ES7 Basic ES7 polyfills for Sugar methods. Can be removed if ES7 is supported.
Function Lazy, partial, and debounced functions, plus memoization and more.
Number Number formatting, precision rounding, Math aliases, and more.
Object Object creation, manipulation, comparison, type checking, and more.
Range Date, Number, and String range objects.
RegExp RegExp escaping and flag manipulation.
String String manupulation, encoding, truncation, formatting, and more.
Inflections Pluralization and support for acronyms and humanized strings.
Language Script detection, full/half-width and Hiragana-Katakana conversion.

Extending

Sugar's core feature is its ability to extend native prototypes to allow working directly with enhanced Javascript objects. This functionality has changed from earlier versions to become opt-in and allow fine-grained control through the extend method. Individual namespaces such as Date or String can now be explictly included or excluded, as can individual methods.

When extending, methods on the Sugar global are mapped to their associated native depending on their type. For example, the instance method Sugar.Array.unique becomes Array.prototype.unique, while the static method Sugar.Array.create becomes Array.create. Note that Sugar will never extend methods onto Object.prototype by default. For more, see object methods.

Most methods listed above in the docs follow this pattern with the exception of polyfills – which are immediately applied to natives and do not go through extend – and accessors, which are static methods only called on the Sugar global.

If extend is called without special conditions (except, etc), then methods defined later will be immediately mapped so that extend does not need to be called multiple times.

Note that the Sugar global itself is an alias to extend to allow simpler syntax in Node environments (example below).

// Extend all methods Sugar.extend();
// Extend all Date methods Sugar.Date.extend();
// Extend specific namespaces Sugar.extend({ namespaces: [Date, String] });
// Exclude specific namespaces Sugar.extend({ except: [Array, Number] });
// Extend specific Array methods Sugar.Array.extend({ methods: ['first', 'last'] });
// Exclude specific Array methods Sugar.Array.extend({ except: ['unique', 'average'] });
// Node exports is an alias to .extend require('sugar')();

To extend or not to extend?

Although Sugar has long been a proponent of safe extension of native Javascript objects, the decision to make this functionality opt-in is due to the fact that in the end there are still times when extending natives is not appropriate or desirable.

The most major of these is when developing a plugin or middleware. Although extending can be done safely, this should always be a conscious decision that the end user, or team, is well aware of. Extending natives in middleware means that its consumers may encounter issues because they are not aware that the global state has changed. If there is any chance that your code may be consumed later by a third party, it is strongly recommended not to use extend. Fortunately, chainables are now provided instead as a middle ground to allow working with Javascript objects in a similar manner without having to extend.

Sugar also believes that if native extension is to be done, it should be handled by a single library alone. Co-existing in the global namespace creates a potential for confusion caused by either library conflicting with the other's methods that simply isn't worth the value they provide. There are a number of libraries that augment natives, most often as a side-effect, and it is recommended that when using these libraries your project should not use extend.

Chainables

In situations where extending is not appropriate or desired, chainables can offer a nice middle ground to allow working with Javascript objects in a similar manner.

Chainables are very simple to use. They are created using the Sugar namespaces themselves, which double as constructor functions, by passing in a value that the chainable will wrap as a property called raw. This property is forwarded to both Sugar methods and native methods which exist on the chainable prototype. Accessing the raw property will retrieve the resulting value.

The Array and Date modules, when included, allow slightly enhanced chainable functionality by forwarding the constructor to their create method, allowing for some expressive shortcuts.

Note that chainable constructors are also factory functions as well, meaning that they do not require using the new keyword. Lastly, chainables also have a valueOf method that returns the raw property. This means that they can be used with vanilla Javascript operators. Note however that this will result in a raw value, which would have to be wrapped again to continue using as a chainable object.

Some live examples on this site can toggle between "Default" and "Extended" modes. Chainables should be identical to "Extended" with the understanding that they must be created first.
var n = new Sugar.Number(5); n.log().pow(2).round(2).raw;
var d = Sugar.Date('tomorrow'); d.addDays(5).relative().raw;
Sugar.String('foo') + Sugar.String('bar');

Polyfills

The ES5, ES6, and ES7 modules provide polyfill methods. These methods are mapped directly onto natives when functionality is broken or missing, and cannot be called directly on the Sugar global object. However, note that certain enhanced methods such as Array#map, have both spec-following polyfills found in the ES5 or ES6 module, and enhanced functionality that is provided elsewhere. The enhanced functionality works as with other normal Sugar methods – called either on the global object or on natives when extending. They do extra work to provide useful shortcuts, and finally call the native implementation under the hood.

Note that the ES5 module is not included in the default build. It can be added by creating a custom build.

Enhanced Methods

Some of Sugar's most powerful features are provided as "enhanced methods". These are methods that have the same name as built-in methods but allow arguments that would otherwise throw an error. For example, find and filter on Sugar.Array allow a string argument that is a shortcut to a function.

When extending natives with Sugar, having the same name effectively means that the built-in method will be overwritten. Sugar attempts to do this as cautiously as possible – only arguments that would otherwise throw an error are allowed, and anything else is immediately sent to the native implementation. In fact, in general, enhanced methods simply build up arguments to be handed off to the native implementation.

Nevertheless, overriding built-in methods is understandably controversial, so Sugar provides a way to opt-out of this behavior when extending. You can pass false for either the enhance flag to opt out of all enhancements, or a flag like enhanceArray to opt out of a specific namespace. Note that these flags simply prevent overriding built-in methods with the same name, so other methods with similar behavior will still be extended. For example, Array#none allows matching shortcuts, but is simply applying the inverse of Array#some. As there is no naming collision, this method will still be extended, even if the enhance flag is off. Also note that these enhancements can still be used any time when called as static methods on the Sugar global, or when using chainables.

Lastly, note that enhanced methods are defined first as polyfills, and again later in other modules, allowing the polyfill functionality to be consumed separately from the enhancement. For brevity they are only listed once in the method list.

Current enhancements include array matching shortcuts, deep property mapping, and enhancing String#includes to allow a regex.

users.map('name');
names.find(/^H/);
Sugar.extend({ enhance: false // Disallow all enhancements });
Sugar.extend({ enhanceArray: false // Disallow Array enhancements });

Object Methods

By default, Sugar will not touch Object.prototype as there are a number of associated risks that can easily create difficult to track down bugs, often in code you don't control. As a result, when extending, Object methods are mapped as static functions on the global (not the prototype).

However, object instance methods can still be enjoyed through the use of chainables. This usage replaces "extended objects" in previous versions of Sugar, and can greatly enhance the expressiveness of your code.

The documentation reflects these points by giving all Object examples in static form, however note that methods are still marked as "instance" to distinguish them when using chainables.
// Using static methods Sugar.Object.keys(Sugar.Object.add(obj1, obj2))
// Using chainables var obj = new Sugar.Object(obj1); obj.add(obj2).keys().raw

Note that chainables can be used at any time, and do not touch native prototypes.

Finally, if you're feeling adventurous (and you generally have control over the code in your project) you can force Sugar to extend Object.prototype at your own risk using the objectPrototype flag. Note that even when using this flag the methods get and set are not extended as they have special meaning as prototype methods.

Sugar.extend({ objectPrototype: true }); obj1.add(obj2).keys();

Deep Properties

Methods that support deep properties will allow a dot or square brackets as special tokens. They will attempt to traverse into the object to retrieve the property, returning undefined if any namespace does not exist along the way.

Additionally, a .. separator inside the brackets is "range" notation, and will return the specified numerical range. Range members may be negative, which will be an offset from the end of the array.

In the case of Object.set, namespaces that do not exist will be created, and will be initialized to either an empty object or an empty array, depending on whether dot or square bracket syntax was used. The token [] carries the special meaning of "last index + 1", and effectively pushes the value onto the end of the array.

Properties with dot or square bracket literals will not work with deep property notation. Simply use standard square bracket notation instead, or pass a function for methods that allow deep properties as a mapping shortcut.
Object.get(users[0], 'currencies.usd.balance')
Object.get(users[0], 'profile.addresses[0].city')
Object.set(users[0], 'profile.addresses[2].city', 'Sao Paulo')
Object.set(users[0], 'profile.addresses[]', address)
users.average('currencies.usd.balance')
users.map('profile.addresses[0].street')
users.map('profile.addresses[-1].street')
users.map('profile.addresses[0..1].city')

Array Matching

A number of native Javascript array methods such as filter accept "matching functions" which match elements in the array by returning a boolean. Sugar takes this concept and enhances it by allowing shortcuts that build matching functions and hand them off to the native implemenation:

  • Strings, numbers, and booleans will match using strict equality ===. These shortcuts can be used to find simple literals in an array of primitives.

  • Arrays will perform deep matching when matching nested arrays.

  • Regular expressions will call test to match against an array of strings.

  • Dates will call getTime internally to match by time value.

  • Plain objects perform "fuzzy matching", which matches specific properties. Object matchers can be as deep as necessary, and allow the same values listed above as well as functions, making complex matches possible. For example, if { name: /^[a-f]/ } is passed, it will match any object with a name property that starts with a-f.

  • Non-plain objects such as DOM Elements or Events match by strict equality.

['a','b','c'].every('b')
['a','b','c'].some('b')
['a','b','c'].findIndex('b')
[[1,2],[5,6],[4,3]].findIndex([4,3])
names.find(/lly$/)
names.filter(/^H/)
users.find({ age: 32 })

Date Parsing

Sugar's Date.create method is capable of parsing numerous formats. Some examples are listed below. You can try them out in the text box:

Enter a date or click below.
  • now
  • today
  • this week
  • last year
  • next month
  • the 15th
  • 3pm Wednesday
  • in 30 minutes
  • in half a year
  • five years ago
  • yesterday at 4pm
  • half an hour ago
  • an hour from now
  • 6:30pm in three days
  • the 4th of July
  • next week Thursday
  • the end of February
  • two weeks from today
  • the end of next week
  • next Saturday at 10am
  • the first day of 2013
  • four days after Monday
  • March 15th of last year
  • two days after tomorrow
  • the last day of February
  • Sunday, January 15th 2012
  • the beginning of this month
  • the 2nd Tuesday of November
  • 5-2002
  • 8/25/1978
  • 8-25-1978
  • 8.25.1978
  • 2012-12-31
  • 2016-Mar-18
  • 22 August
  • April 2012
  • June 3rd, 2005
  • 1 Dec. 2016
  • 17760523T024508+0830
  • 1997-07-16T19:20:30+01:00
  • 08-25-1978 11:42:32.488am
  • Wed, 03 Jul 2008 08:00:00 EST

Sugar is also capable of parsing dates in other languages. For more, see Date Locales. Although most of the formats are listed here, this list is not exhaustive. The compiledFormats property of the locale object (accessed with getLocale) contains the exact formats used.

Timezones

Note Sugar does not deal with timezone abbreviations (i.e. "PST", etc). Timezone offsets will be correctly parsed if they are in ISO-8601 format (`+09:00`, `+0900`, or `Z` for UTC), however if an abbreviation exists it will be ignored. Sugar however plays nicely with other libraries that offer full timezone support such as timezone.js.

UTC Dates

The `Date.create` method allows two options for dealing with UTC dates. `fromUTC` will parse the string as UTC, but return a normal date. In contrast, `setUTC` tells Sugar to use methods like `getUTCHours` when handling the date, and is usually used when the date needs to be formatted as UTC. Native methods like `getHours` still return local values.

ISO-8601

Sugar natively supports ISO-8601 as one of its core formats. Most modern browsers can also parse this format, however due to certain issues, inconsistencies exist with dates that don't specify a timezone offset (either `Z` or `+-hh:mm`). To ensure compatibility, dates such as server timestamps should always supply an offset. If they do not, Sugar will correctly parse these formats as local time (as per ISO-8601), however be aware that this may differ from browser parsing. If UTC time is required, `fromUTC` will force the date to be parsed as UTC time.

Custom Parsing Formats

The goal of Sugar's date module is to parse any standard date format in any language. In theory, it should be rare enough that a custom format should be required, although this depends on the locale. If a common format is missing, please consider contributing back to the project by raising an issue. However, locale objects provide an addFormat method that makes it easy to add a custom format if needed.

addFormat accepts a format string that contains "parsing tokens" marked with {}. These parsing tokens map to capturing groups that will capture input for that field. For example, {weekday} will parse all weekdays in the locale. Parsing tokens can be make optional with ?, use alteration with |, or allow a subset of an array with :. For example, {yyyy|yy} will allow either 4 or 2 digit years. To make the entire group optional, simply use standard regex non-capturing groups like (?:{yyyy|yy})?. Be sure to string escape special characters like \\d. Anything outside of a parsing token will become part of the regex. Any standard regex token can be used, except for other capturing groups. Spaces in the string will be made optional. To make them required use \\s instead.

Parsing Tokens

Token Value
{weekday} Weekdays and weekday abbreviations (Monday, Mon).
{months} Months and abbreviations (January, Jan).
{month} A shortcut allowing both numeric and text months.
{yyyy} 4 digit year.
{yy} 2 digit year.
{MM} 1-2 digit month.
{dd} 1-2 digit date.
{hh} 1-2 digit hours.
{ihh} 1-2 digit hours with trailing decimal (ISO-8601).
{mm} 2 digit minutes.
{imm} 2 digit minutes with trailing decimal (ISO-8601).
{ss} 2 digit seconds with trailing decimal.
{ampm} AM or PM
{time} A shortcut for {hh}(?::{mm}(?::{ss})?)? {ampm?}.
{day} Modifiers like "today" or "tomorrow".
{shift} Modifiers like "next" or "last" that indicate an offset.
{sign} Modifiers like "ago" or "from now" that indicate time direction.
{edge} Modifiers like "beginning" and "end" that indicate the edge of a unit.
{unit} A units from "milliseconds" to "years" indicating a relative format.
{num} A number to indicate an amount in a relative format using {unit}.
{half} Literal "half" indicating 0.5 in relative formats.
{midday} Modifiers like "noon" and "midnight".
{tzSign} A sign (+-) indicating the timezone offset direction.
{tzHour} 2 digit timezone hours offset.
{tzMinute} 2 digit timezone minutes offset.
{tzOffset} A shortcut for the full UTC timezone offset (ISO-8601).
{GMT} Literal "GMT" token indicating UTC time or offset.
{Z} Literal "Z" token indicating UTC time (ISO-8601).
{timestamp} A unix timestamp in milliseconds.
{yearSign} A sign (+-) indicating the "year" direction.

If the parsing tokens themselves are not enough, you can pass an array as the second argument to addFormat. This array indicates an explicit mapping of any raw capturing groups in the first argument to the resulting fields.

Sugar.Date.getLocale('en').addFormat('{month}'); Sugar.Date.create('January');
Sugar.Date.getLocale('en').addFormat("{months?} (?:{year}|'{yy})"); Sugar.Date.create("February of '82");
Sugar.Date.getLocale('en').addFormat('{num} {unit:6-7} {sign}'); Sugar.Date.create('2 months ago'); Sugar.Date.create('5 years from now');
var loc = Sugar.Date.getLocale('en'); var arr = ['date', 'hours', 'minutes']; loc.addFormat('(\\\\d+)(?:th|st|rd)@(\\\\d+):(\\\\d+)', arr); Sugar.Date.create('15th@4:15');

Date Formatting

Sugar allows fine grained control over date to string formatting with the format method. There are two types of tokens that can be used in the format string, strftime and LDML. strftime tokens are commonly used and well known to programmers of various other languages, while LDML is often more intuitive, and easier to remember. LDML tokens in Sugar are demarcated with curly braces {}. Tokens of either type can be used interchangeably, although this is generally not good practice.

Sugar also has 4 pre-defined formats: short, medium, long, and full. They can be used either as LDML tokens or called directly on the date as instance methods. Finally, the relative method returns the date in a text format relative to the current time.

strftime tokens

Token Value
%a Abbreviated day of the week (Sun)
%A Full day of the week (Sunday)
%b Abbreviated month name (Jan)
%B Full month name (January)
%c Common timestamp format (Thu Aug 5 2010 2:03 PM)
%C Century as 2 digit string (20)
%d 2-digit day of the month with 0 ("05")
%D American month first slash format (08/05/12)
%e 2-digit day of the month with space (" 5")
%F Common datestamp format (2010-08-05)
%g ISO8601 week year (2 digits)
%G ISO8601 week year (4 digits)
%h Abbreviated month name (Jan)
%H 2-digit hours in 24-hour format (13)
%I 2-digit hours in 12-hour format (01)
%j Day of the year (365)
%m 2-digit month
%M 2-digit minutes
%p AM/PM (uppercase)
%P am/pm (lowercase)
%r 12 hour clock time with seconds (02:03:02 PM)
%R 24 hour clock time without seconds (14:03)
%S 2-digit seconds
%T 24 hour clock time without seconds (14:03:02)
%u ISO8601 day of the week (Sunday = 7)
%U 2-digit week number (First Sunday of year = 01, prev = 00)
%V 2-digit ISO-8601 week number. First week of the year has at least 4 weekdays, Monday is the start of the week
%w Day of the week (Sunday = 0)
%W 2-digit numeric week of the year. First Monday is the first week
%x Locale based representation of the date (ex. 08/05/2010)
%X Locale based representation of the time (ex. 2:03 PM)
%Y 4-digit year

LDML tokens

Token Value
{ms} Milliseconds
{S} Milliseconds
{SSS} 3-digit milliseconds
{s} Seconds
{ss} 2-digit seconds
{seconds} Seconds
{minutes} Minutes
{m} Minutes
{mm} 2-digit minutes
{hours} Hours (12 hour clock)
{h} Hours (12 hour clock)
{hh} 2-digit hours (12 hour clock)
{hours} Hours (12 hour clock)
{H} Hours (24 hour clock)
{HH} 2-digit hours (24 hour clock)
{date} Date
{d} Date
{dd} 2-digit date
{do} Ordinal date (5th)
{dow} Lowercase abbreviated day of the week (sun)
{Dow} Abbreviated day of the week (Sun)
{e} Numeric day of the week (1)
{eo} Ordinal numeric day of the week (1st)
{weekday} Lowercase day of the week (sunday)
{Weekday} Day of the week (Sunday)
{D} Day of the year (365)
{DDD} 3-digit day of the year (365)
{full} A full format specific to the locale
{gg} 2-digit week year
{gggg} 4-digit week year
{GG} 2-digit ISO8601 week year
{GGGG} 4-digit ISO8601 week year
{long} A long format specific to the locale
{M} Numeric month
{MM} 2-digit numeric month
{medium} A medium format specific to the locale
{month} Lowercase month name (january)
{Month} Month name (January)
{mon} Lowercase abbreviated month name (jan)
{Mon} Abbreviated month name (Jan)
{Mo} Ordinal month (1st)
{yy} 2-digit year (10)
{yyyy} 4-digit year (2010)
{year} 4-digit year (2010)
{Q} Quarter
{short} A short format specific to the locale
{stamp} A timestamp format specific to the locale
{t} AM/PM as 1 lowercase letter (a/p)
{T} AM/PM as 1 uppercase letter (A/P)
{tt} am/pm
{TT} AM/PM
{time} Time string specific to the locale
{w} Locale based week number
{ww} 2-digit locale based week number
{wo} Ordinal locale based week number
{W} ISO8601 week number
{WW} 2-digit ISO8601 week number
{Wo} Ordinal ISO8601 week number
{X} Unix timestamp
{x} Unix timestamp (milliseconds)
{Z} Timezone offset with colon (+09:00)
{ZZ} Timezone offset without colon (+0900)

Aliases

Token Value
ISO8601 {yyyy}-{MM}-{dd}T{HH}:{mm}:{ss}.{SSS}{Z}
RFC1123 {Dow}, {dd} {Mon} {yyyy} {HH}:{mm}:{ss} {tz}
RFC1036 {Weekday}, {dd}-{Mon}-{yy} {HH}:{mm}:{ss} {tz}
today.format('{yyyy}-{MM}-{dd}');
today.format('%Y-%m-%d');
today.format('ISO8601');
today.format('RFC1123');
jul.format('{long}');
jul.long();

Date Locales

Sugar is capable of both parsing and formatting dates in multiple locales. The default build includes English as the base locale. Additional locales can be added either by adding them in a custom build or by simply including the locale definition files after Sugar is loaded (in npm, these are in the locales directory). Once added, locales can be set globally with the setLocale method, or passed to methods:

// Set "en" as the global locale Date.setLocale('en');
Date.create('一時間前', 'ja');
Date.create("d'ici 5 heures", 'fr');
jan.relative('ru');
new Date().short('fi');
new Date().medium('zh-CN');
new Date().long('es');
new Date().short('en')
new Date().short('en-US')
new Date().short('en-GB')
new Date().short('en-AU')
new Date().short('en-CA')
The default locale is `en`, which is an alias for `en-US`, or American English. However, `en-GB`, `en-AU`, and `en-CA` are also bundled with the date module. The main difference is that only American English allows the month first slash format `2/15/2015`. Other English locales will parse this as `dd/mm/yyyy`. Additionally, English variants also have slightly different formatting aliases (`short`, `medium`, `long`, `full`, and `stamp`).

Modifying Locales

Sugar provides access to locale objects through getLocale. They are exposed mostly for introspection, as it is usually better to change the locale definition itself if possible. However, a method addFormat exists on the locale object to allow formats to be added at runtime. For more, see Date Parsing.

Creating Locales

If a locale is missing, it can be added with addLocale. This method takes a locale definition object. Refer to an existing locale as a good starting point for creating this object.

Most fields allow a simple alternating format to keep them compact. A colon : demarcates a prefix and pipe | indicates suffix alternation. For example, in the English definition file Sep:tember|t| is equivalent to September|Sept|Sep. Any alternate form will parse, but the order is important for date formatting as the first alternate will be the "full" form, and the second alternate will be the "abbreviated" form (tokens like {Mon} for {Month} or {Dow} for {Weekday}). Plural forms for units likewise use alternates when the definition has plural set to true.

Parsing formats are defined in parse, timeParse, and timeFrontParse. The last two will add time parsing tokens either on the front or back of the format. Any token demarcated with {} will become a capturing group. Adding ? to the token makes it optional, and | can also be used within the braces for alternation. Any regex token can be used between the curly brace tokens except for capturing groups, whose order is important to the regex parsing. For example, to have alternating tokens that are optional, use (?:{token1|token2})?. Tokens are listed in Date Parsing. Common tokens that are integral to a format but carry no value, such as "of" in English or "la" in French can be added to the "tokens" array, and accessed by a number signifying an index, such as {0}.

past, future, relative, and duration are output formats that allow formatting tokens (listed in Date Formatting, but may also be functions for grammatically complex languages (see Russian for an example). modifiers are special tokens that should be fairly easy to follow (see English for an example). For the edge modifier, values of -2 and 2 are the beginning of the unit and end of the unit respectively, where a value of 1 will effectively reset the time, so is used for the "last day of ...", which is not exactly the edge. -1 is unused.

Finally, if you have created a locale definition, please share it with the community by opening a pull request!

Ranges

Sugar ranges provide a lightweight, convenient way to handle a range of values or time that have a distinct start and end. All ranges have only a start and end as properties, but can be compared, combined, and iterated over.

Three types of ranges exist: Date, Number, and String. They are created through the range method on each namespace by passing a start and end value. Range methods appear in the API reference above and can be included or excluded in custom builds, however they differ from standard Sugar methods in that they are always called as instance methods on range objects, and never as static methods.

Note that ranges will accept a start value greater than the end. In this case iteration methods will count down instead of up. Other methods will function identically.

Sugar.Number.range(5, 10).contains(8);
Sugar.String.range('a', 'c').toArray();
Sugar.Date.range(today, tomorrow).hours();
Sugar.Date.range('Tuesday from 1pm to 6pm').hours();

Accessors

Accessor methods provide a way to access Sugar internals that affect multiple methods. For example, setting decimal in setOption on Number will control the decimal marker in number formats. Accessors are always called on the Sugar global object and are never extended onto natives.

The setOption accessor is a pattern that allows quick access to options specific to the namespace. Passing any value will override the option, while passing null will restore the default. This allows options to be quickly switched on and off.

Sugar.Number.setOption('decimal', ','); Sugar.Number.format(49.95);
Sugar.String.addAcronym('SSL'); Sugar.String.camelize('ssl_error');

Immutability

For better or worse, Objects, Arrays, and Dates are all inherently mutable types in Javascript. Although most methods in Sugar are non-destructive, as a library that is designed to work well with natives, a number of methods do exist that will modify the object they operate on. These methods are all clearly documented, and thought has been given to their naming in order to have a more intuitive API.

add and subtract on Arrays and Objects are designed to correlate to operators, and will always return a new object. In contrast, remove, insert, and append are intended to imply mutability. exclude is offered as a non- destructive alias to remove. sortBy follows sort in choosing to modify the array instance itself. Finally, in following with the native Date API, Sugar chooses to make all Date instance methods (that do not return primitives) modify their date object as well.

Below is a list of all destructive methods in Sugar. Note that when non- destructive aliases do not exist, all 3 classes provide a clone method that can be called first to prevent mutation of the object.

Class Method Alias
Array append add
insert add (with options)
remove exclude
removeAt -
sortBy -
Object merge add
mergeAll addAll
defaults add (with options)
remove exclude
Date addUnits -
advance -
beginningOfUnit -
endOfUnit -
reset -
rewind -
set -
setISOWeek -
setUTC -
setWeekday -

Array Sorting

Array#sortBy uses a number of sort options set in the setOption accessor. Default options provide the best possible results for the most major world languages, but can be modified. sortOrder is by default the following string:

AÁÀÂÃĄBCĆČÇDĎÐEÉÈĚÊËĘFGĞHıIÍÌİÎÏJKLŁMNŃŇÑOÓÒÔPQRŘSŚŠŞTŤUÚÙŮÛÜVWXYÝZŹŻŽÞÆŒØÕÅÄö

sortIgnore is null by default, so punctuation and other special characters will affect sorting. sortIgnoreCase is true by default so case will be ignored. Note however that the above ordering actually includes lowercase characters after uppercase (not shown), so if sortIgnoreCase is set to false, their order will still be properly respected.

sortEquivalents is a map containing diacritic (accented) letters that are known to be equivalents in major European languages, most notably French and German. This map can be modified simply by setting the properties, or reset by setting it to {}. Note that both cases must be specified separately. Equivalents are as follows (also includes lowercase equivalents):

  • A: ÁÀÂÃÄ
  • C: Ç
  • E: ÉÈÊË
  • I: ÍÌİÎÏ
  • O: ÓÒÔÕÖ
  • S: ß
  • U: ÚÙÛÜ

Polish and Scandanavian Languages

The defaults handle most of the major world languages, however there are some exceptions. Polish orders the character Ç as a separate letter, while French treats it as a C. Also, Scandanavian languages like Swedish and Norwegian order Ä and Ö after Z, where German orders them as A and O. In such cases, simply removing that entry from the equivalents map will result in the correct order for these languages.

Other Limitations

Proper collation algorithms are complex, and can handle other situations which Sugar cannot. Most notably are expansions and contractions of multiple characters, such as ll in Spanish. In such cases, Array#sortBy itself may provide a workaround using the mapped sort value. For example, replacing ll with a distinct character or token and including it in sortOrder would solve the contraction issue for a strict Spanish sort. This works because the return value of the mapping function is only used for sort ordering and has no effect on actual content of the array. Expansions could likewise be added as required.

Support

Sugar features very robust support, and with the inclusion of polyfills will function in pre-ES5 environments down to IE 6-8. Sugar is tested in all major browsers (including mobile versions):

  • Chrome
  • Firefox
  • Safari
  • Opera
  • Opera Mini
  • Microsoft Edge
  • Internet Explorer (6-11)