Coder Social home page Coder Social logo

underscore.string's Introduction

The stable release documentation can be found here https://epeli.github.io/underscore.string/

Underscore.string Build Status

Javascript lacks complete string manipulation operations. This is an attempt to fill that gap. List of build-in methods can be found for example from Dive Into JavaScript. Originally started as an Underscore.js extension but is a full standalone library nowadays.

Upgrading from 2.x to 3.x? Please read the changelog.

Usage

For Node.js, Browserify and Webpack

Install from npm

npm install underscore.string

Require individual functions

var slugify = require("underscore.string/slugify");

slugify("Hello world!");
// => hello-world

or load the full library to enable chaining

var s = require("underscore.string");

s("   epeli  ").trim().capitalize().value();
// => "Epeli"

but especially when using with Browserify the individual function approach is recommended because using it you only add those functions to your bundle you use.

In Meteor

From your Meteor project folder

    meteor add underscorestring:underscore.string

and you'll be able to access the library with the s global from both the server and the client.

s.slugify("Hello world!");
// => hello-world

s("   epeli  ").trim().capitalize().value();
// => "Epeli"

Others

The dist/underscore.string.js file is an UMD build. You can load it using an AMD loader such as RequireJS or just stick it to a web page and access the library from the s global.

Underscore.js/Lo-Dash integration

It is still possible use as Underscore.js/Lo-Dash extension

_.mixin(s.exports());

But it's not recommended since include, contains, reverse and join are dropped because they collide with the functions already defined by Underscore.js.

Lo-Dash-FP/Ramda integration

If you want to use underscore.string with ramdajs or Lo-Dash-FP you can use underscore.string.fp.

npm install underscore.string.fp
var S = require('underscore.string.fp');
var filter = require('lodash-fp').filter;
var filter = require('ramda').filter;

filter(S.startsWith('.'), [
  '.vimrc',
  'foo.md',
  '.zshrc'
]);
// => ['.vimrc', '.zshrc']

Download

API

Individual functions

numberFormat(number, [ decimals=0, decimalSeparator='.', orderSeparator=',']) => string

Formats the numbers.

numberFormat(1000, 2);
// => "1,000.00"

numberFormat(123456789.123, 5, ".", ",");
// => "123,456,789.12300"

levenshtein(string1, string2) => number

Calculates [Levenshtein distance][ld] between two strings. [ld]: http://en.wikipedia.org/wiki/Levenshtein_distance

levenshtein("kitten", "kittah");
// => 2

capitalize(string, [lowercaseRest=false]) => string

Converts first letter of the string to uppercase. If true is passed as second argument the rest of the string will be converted to lower case.

capitalize("foo Bar");
// => "Foo Bar"

capitalize("FOO Bar", true);
// => "Foo bar"

decapitalize(string) => string

Converts first letter of the string to lowercase.

decapitalize("Foo Bar");
// => "foo Bar"

chop(string, step) => array

chop("whitespace", 3);
// => ["whi", "tes", "pac", "e"]

clean(string) => string

Trim and replace multiple spaces with a single space.

clean(" foo    bar   ");
// => "foo bar"

cleanDiacritics(string) => string

Replace diacritic characters with closest ASCII equivalents. Check the source for supported characters. Pull requests welcome for missing characters!

cleanDiacritics("ääkkönen");
// => "aakkonen"

chars(string) => array

chars("Hello");
// => ["H", "e", "l", "l", "o"]

swapCase(string) => string

Returns a copy of the string in which all the case-based characters have had their case swapped.

swapCase("hELLO");
// => "Hello"

include(string, substring) => boolean

Tests if string contains a substring.

include("foobar", "ob");
// => true

count(string, substring) => number

Returns number of occurrences of substring in string.

count("Hello world", "l");
// => 3

escapeHTML(string) => string

Converts HTML special characters to their entity equivalents. This function supports cent, yen, euro, pound, lt, gt, copy, reg, quote, amp, apos.

escapeHTML("<div>Blah blah blah</div>");
// => "&lt;div&gt;Blah blah blah&lt;/div&gt;"

unescapeHTML(string) => string

Converts entity characters to HTML equivalents. This function supports cent, yen, euro, pound, lt, gt, copy, reg, quote, amp, apos, nbsp.

unescapeHTML("&lt;div&gt;Blah&nbsp;blah blah&lt;/div&gt;");
// => "<div>Blah blah blah</div>"

insert(string, index, substring) => string

insert("Hellworld", 4, "o ");
// => "Hello world"

replaceAll(string, find, replace, [ignorecase=false]) => string

replaceAll("foo", "o", "a");
// => "faa"

isBlank(string) => boolean

isBlank(""); // => true
isBlank("\n"); // => true
isBlank(" "); // => true
isBlank("a"); // => false

join(separator, ...strings) => string

Joins strings together with given separator

join(" ", "foo", "bar");
// => "foo bar"

lines(str) => array

Split lines to an array

lines("Hello\nWorld");
// => ["Hello", "World"]

wrap(str, options) => string

Splits a line str (default '') into several lines of size options.width (default 75) using a options.seperator (default '\n'). If options.trailingSpaces is true, make each line at least width long using trailing spaces. If options.cut is true, create new lines in the middle of words. If options.preserveSpaces is true, preserve the space that should be there at the end of a line (only works if options.cut is false).

wrap("Hello World", { width:5 })
// => "Hello\nWorld"

wrap("Hello World", { width:6, seperator:'.', trailingSpaces: true })
// => "Hello .World "

wrap("Hello World", { width:5, seperator:'.', cut:true, trailingSpaces: true })
// => "Hello. Worl.d    "

wrap("Hello World", { width:5, seperator:'.', preserveSpaces: true })
// => "Hello .World"

dedent(str, [pattern]) => string

Dedent unnecessary indentation or dedent by a pattern.

Credits go to @sindresorhus. This implementation is similar to https://github.com/sindresorhus/strip-indent

dedent("  Hello\n    World");
// => "Hello\n  World"

dedent("\t\tHello\n\t\t\t\tWorld");
// => "Hello\n\t\tWorld"

dedent("    Hello\n    World", "  "); // Dedent by 2 spaces
// => "  Hello\n  World"

reverse(string) => string

Return reversed string:

reverse("foobar");
// => "raboof"

splice(string, index, howmany, substring) => string

Like an array splice.

splice("https://[email protected]/edtsech/underscore.strings", 30, 7, "epeli");
// => "https://[email protected]/epeli/underscore.strings"

startsWith(string, starts, [position]) => boolean

This method checks whether the string begins with starts at position (default: 0).

startsWith("image.gif", "image");
// => true

startsWith(".vimrc", "vim", 1);
// => true

endsWith(string, ends, [position]) => boolean

This method checks whether the string ends with ends at position (default: string.length).

endsWith("image.gif", "gif");
// => true

endsWith("image.old.gif", "old", 9);
// => true

pred(string) => string

Returns the predecessor to str.

pred("b");
// => "a"

pred("B");
// => "A"

succ(string) => string

Returns the successor to str.

succ("a");
// => "b"

succ("A");
// => "B"

titleize(string) => string

titleize("my name is epeli");
// => "My Name Is Epeli"

camelize(string, [decapitalize=false]) => string

Converts underscored or dasherized string to a camelized one. Begins with a lower case letter unless it starts with an underscore, dash or an upper case letter.

camelize("moz-transform");
// => "mozTransform"

camelize("-moz-transform");
// => "MozTransform"

camelize("_moz_transform");
// => "MozTransform"

camelize("Moz-transform");
// => "MozTransform"

camelize("-moz-transform", true);
// => "mozTransform"

classify(string) => string

Converts string to camelized class name. First letter is always upper case

classify("some_class_name");
// => "SomeClassName"

underscored(string) => string

Converts a camelized or dasherized string into an underscored one

underscored("MozTransform");
// => "moz_transform"

dasherize(string) => string

Converts a underscored or camelized string into an dasherized one

dasherize("MozTransform");
// => "-moz-transform"

humanize(string) => string

Converts an underscored, camelized, or dasherized string into a humanized one. Also removes beginning and ending whitespace, and removes the postfix '_id'.

humanize("  capitalize dash-CamelCase_underscore trim  ");
// => "Capitalize dash camel case underscore trim"

trim(string, [characters]) => string

Trims defined characters from begining and ending of the string. Defaults to whitespace characters.

trim("  foobar   ");
// => "foobar"

trim("_-foobar-_", "_-");
// => "foobar"

ltrim(string, [characters]) => string

Left trim. Similar to trim, but only for left side.

rtrim(string, [characters]) => string

Right trim. Similar to trim, but only for right side.

truncate(string, length, [truncateString = '...']) => string

truncate("Hello world", 5);
// => "Hello..."

truncate("Hello", 10);
// => "Hello"

prune(string, length, pruneString) => string

Elegant version of truncate. Makes sure the pruned string does not exceed the original length. Avoid half-chopped words when truncating.

prune("Hello, world", 5);
// => "Hello..."

prune("Hello, world", 8);
// => "Hello..."

prune("Hello, world", 5, " (read a lot more)");
// => "Hello, world" (as adding "(read a lot more)" would be longer than the original string)

prune("Hello, cruel world", 15);
// => "Hello, cruel..."

prune("Hello", 10);
// => "Hello"

words(str, delimiter=/\s+/) => array

Split string by delimiter (String or RegExp), /\s+/ by default.

words("   I   love   you   ");
// => ["I", "love", "you"]

words("I_love_you", "_");
// => ["I", "love", "you"]

words("I-love-you", /-/);
// => ["I", "love", "you"]

words("   ")
// => []

sprintf(string format, ...arguments) => string

C like string formatting. Makes use of the sprintf-js package.

This function will be removed in the next major release, use the sprintf-js package instead.

sprintf("%.1f", 1.17);
// => "1.2"

pad(str, length, [padStr, type]) => string

pads the str with characters until the total string length is equal to the passed length parameter. By default, pads on the left with the space char (" "). padStr is truncated to a single character if necessary.

pad("1", 8);
// => "       1"

pad("1", 8, "0");
// => "00000001"

pad("1", 8, "0", "right");
// => "10000000"

pad("1", 8, "0", "both");
// => "00001000"

pad("1", 8, "bleepblorp", "both");
// => "bbbb1bbb"

lpad(str, length, [padStr]) => string

left-pad a string. Alias for pad(str, length, padStr, "left")

lpad("1", 8, "0");
// => "00000001"

rpad(str, length, [padStr]) => string

right-pad a string. Alias for pad(str, length, padStr, "right")

rpad("1", 8, "0");
// => "10000000"

lrpad(str, length, [padStr]) => string

left/right-pad a string. Alias for pad(str, length, padStr, "both")

lrpad("1", 8, '0');
// => "00001000"

toNumber(string, [decimals]) => number

Parse string to number. Returns NaN if string can't be parsed to number.

toNumber("2.556");
// => 3

toNumber("2.556", 1);
// => 2.6

toNumber("999.999", -1);
// => 990

strRight(string, pattern) => string

Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found.

strRight("This_is_a_test_string", "_");
// => "is_a_test_string"

strRightBack(string, pattern) => string

Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the right of the pattern or all string if no match found.

strRightBack("This_is_a_test_string", "_");
// => "string"

strLeft(string, pattern) => string

Searches a string from left to right for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found.

strLeft("This_is_a_test_string", "_");
// => "This";

strLeftBack(string, pattern) => string

Searches a string from right to left for a pattern and returns a substring consisting of the characters in the string that are to the left of the pattern or all string if no match found.

strLeftBack("This_is_a_test_string", "_");
// => "This_is_a_test";

stripTags(string) => string

Removes all html tags from string.

stripTags("a <a href=\"#\">link</a>");
// => "a link"

stripTags("a <a href=\"#\">link</a><script>alert(\"hello world!\")</script>");
// => "a linkalert("hello world!")"

toSentence(array, [delimiter, lastDelimiter]) => string

Join an array into a human readable sentence.

toSentence(["jQuery", "Mootools", "Prototype"]);
// => "jQuery, Mootools and Prototype";

toSentence(["jQuery", "Mootools", "Prototype"], ", ", " unt ");
// => "jQuery, Mootools unt Prototype";

toSentenceSerial(array, [delimiter, lastDelimiter]) => string

The same as toSentence, but adjusts delimeters to use Serial comma.

toSentenceSerial(["jQuery", "Mootools"]);
// => "jQuery and Mootools"

toSentenceSerial(["jQuery", "Mootools", "Prototype"]);
// => "jQuery, Mootools, and Prototype"

toSentenceSerial(["jQuery", "Mootools", "Prototype"], ", ", " unt ");
// => "jQuery, Mootools, unt Prototype"

repeat(string, count, [separator]) => string

Repeats a string count times.

repeat("foo", 3);
// => "foofoofoo"

repeat("foo", 3, "bar");
// => "foobarfoobarfoo"

surround(string, wrap) => string

Surround a string with another string.

surround("foo", "ab");
// => "abfooab"

quote(string, quoteChar) or q(string, quoteChar) => string

Quotes a string. quoteChar defaults to ".

quote("foo", '"');
// => '"foo"';

unquote(string, quoteChar) => string

Unquotes a string. quoteChar defaults to ".

unquote('"foo"');
// => "foo"

unquote("'foo'", "'");
// => "foo"

slugify(string) => string

Transform text into an ascii slug which can be used in safely in URLs. Replaces whitespaces, accentuated, and special characters with a dash. Limited set of non-ascii characters are transformed to similar versions in the ascii character set such as ä to a.

slugify("Un éléphant à l\'orée du bois");
// => "un-elephant-a-l-oree-du-bois"

Caution: this function is charset dependent

naturalCmp(string1, string2) => number

Naturally sort strings like humans would do. None numbers are compared by their ASCII values. Note: this means "a" > "A". Use .toLowerCase if this isn't to be desired.

Just past it to Array#sort.

["foo20", "foo5"].sort(naturalCmp);
// => ["foo5", "foo20"]

toBoolean(string) => boolean

Turn strings that can be commonly considered as booleas to real booleans. Such as "true", "false", "1" and "0". This function is case insensitive.

toBoolean("true");
// => true

toBoolean("FALSE");
// => false

toBoolean("random");
// => undefined

It can be customized by giving arrays of truth and falsy value matcher as parameters. Matchers can be also RegExp objects.

toBoolean("truthy", ["truthy"], ["falsy"]);
// => true

toBoolean("true only at start", [/^true/]);
// => true

map(string, function) => string

Creates a new string with the results of calling a provided function on every character of the given string.

map("Hello world", function(x) {
  return x;
});
// => "Hello world"

map(12345, function(x) {
  return x;
});
// => "12345"

map("Hello world", function(x) {
  if (x === 'o') x = 'O';
  return x;
});
// => "HellO wOrld"

Library functions

If you require the full library you can use chaining and aliases

s(string) => chain

Start a chain. Returns an immutable chain object with the string functions as methods which return a new chain object instead of the plain string value.

The chain object includes also following native Javascript string methods:

chain.value()

Return the string value from the chain

s("  foo  ").trim().capitalize().value();
// => "Foo"

When calling a method which does not return a string the resulting value is immediately returned

s(" foobar ").trim().startsWith("foo");
// => true

chain.tap(function) => chain

Tap into the chain with a custom function

s("foo").tap(function(value){
  return value + "bar";
}).value();
// => "foobar"

Aliases

strip     = trim
lstrip    = ltrim
rstrip    = rtrim
center    = lrpad
rjust     = lpad
ljust     = rpad
contains  = include
q         = quote
toBool    = toBoolean
camelcase = camelize

Maintainers

This library is maintained by

Licence

The MIT License

Copyright (c) 2011 Esa-Matti Suuronen [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

underscore.string's People

Contributors

amekss avatar bsimpson avatar btoone avatar cartersgenes avatar deleteman avatar dmnd avatar donaldpipowitch avatar dperrymorrow avatar edtsech avatar esamattis avatar funkatron avatar icflorescu avatar jamielinux avatar janraasch avatar kossnocorp avatar lfac-pt avatar mahdavipanah avatar masklinn avatar megawac avatar mondalaci avatar paulborza avatar pgherveou avatar philoye avatar rwz avatar sergiokas avatar seung avatar sixcircuit avatar stoeffel avatar tchak avatar wulftone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

underscore.string's Issues

Pluralize function

_.pluralize('post') // => 'posts'
_.singularize('posts') // => 'post'

or

_.pluralize(1, 'post') //=> 'post'
_.pluralize(2, 'post') //=> 'posts'
_.pluralize(1, 'posts') //=> 'post'

Dasherize - Accented/Special characters are now being converted to dashes

After the fix for issue #89, it seems all characters that are not [A-Za-z0-9] are being converted to dashes.
The behavior prior to the fix for #89 did not do this.

This is an issue when you have accented words and/or special characters like $ in the string you want to dasherize.

téléphone => t-l-phone
foo$bar => foo-bar

startsWith and endsWith are too slow

I propose to change them to:

function strStarts(fnd,str,bol){
    return str.lastIndexOf(fnd,0)==0;
}

function strEnds(fnd,str,bol){
    var i=str.length-fnd.length;
    return str.lastIndexOf(fnd,i)==i;
}

It will be much faster.

It would also be interesting to add a new feature that allows to ignore-case. Something like:

function strStarts(fnd,str,bol){
    return (bol?str.toLowerCase().lastIndexOf(fnd.toLowerCase(),0):str.lastIndexOf(fnd,0))==0;
}

function strEnds(fnd,str,bol){
    var i=str.length-fnd.length;
    return (bol?str.toLowerCase().lastIndexOf(fnd.toLowerCase(),i):str.lastIndexOf(fnd,i))==i;
}

I ran some tests, and even with the new feature is faster than the current method.

Thanks for your time

Email verification

A common string manipulation in JS is to check if an email is valid. Perhaps it belongs in this library? This is a feature request.

Allow conflicting functions via type detection

Maybe you could suggest (or provide a helper function) that conflicting functions could override the underscore equivalents via wrappers that detect whether the argument passed is a String or other Object.

This would avoid potential bugs when someone uses the wrong function for the wrong type.

This is what I have done in my project and it seems to work well:

_.mixin(_.str.exports());

// functions that conflict with _ and _.prototype
_.mixin(_.reduce(['include', 'contains'], function(memo, f) {
  var str = _.str[f], und = _[f];
  memo[f] = function(obj) {
    return (_.isString(obj) ? str : und).apply(this, arguments);
  };
  return memo;
}, {}));

// functions that just conflict with _.prototype
_.each(['reverse'], function(f) {
  var wstr, str = _.str[f], wund = _.prototype[f]; 
  _.mixin({__tmp: str}); // get access to addToWrapper
  wstr = _.prototype.__tmp;
  _[f] = str;
  _.prototype[f] = function() {
    return (_.isString(this._wrapped) ? wstr : wund).apply(this, arguments);
  };
});

Thanks for a great library!

escapeHTML

Hi!

The current implementation of the subj throws if typeof argument !== 'string' which is not uncommon case -- consider numbers, and especially undefined (which is very common case: _.escapeHTML(data['name']) when name is not in data)

Instead of endless sanity checks I propose to use something like:
return String(str||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');

TIA for feedback,
--Vladimir

Empty and whitespace-only strings

I would like to see an empty method that returns true if the string has a length of zero.

I would also like to see a method that returns true if the string only contains whitespace (I don't know how you would call that, blank maybe?).

ljust alias for lpad

Maybe just me but this feels wrong.

lpad adds to the left so I think this is rjust

_.lpad("1", 8, '0')
-> "00000001";

the result is right justified no?

underscore 1.1.7 union(..) bug with underscore.string 1.1.6

Execute this script with node.js and the specified versions:

var _           = require( 'underscore' );
    _.mixin(      require( 'underscore.string' ) );

var x = [{a: 5}, {b: 6}, {c: 7}];
var y = [];
console.log(_.union(x, y));

The result will include only the first element of x. Playing with it a bit, it looks like union(..) will keep integers in the array, while throwing out all objects after the first one.

Now comment out the mixin. The result will be correct.

npm install undescore.string doesn't work

I am using node v0.6.10 and npm v1.1.0-3
These are the contents of npm-debug.log:

info it worked if it ends with ok
verbose cli [ 'node', '/usr/local/bin/npm', 'install', 'underscore.string' ]
info using [email protected]
info using [email protected]
verbose config file /home/alexandru/.npmrc
verbose config file /usr/local/etc/npmrc
verbose config file /usr/local/lib/node_modules/npm/npmrc
verbose caching /mnt/hgfs/oss/sum.js/text-summarization/package.json
verbose loadDefaults [email protected]
verbose from cache /mnt/hgfs/oss/sum.js/text-summarization/package.json
verbose cache add [ 'underscore.string@~2.0.0', null ]
silly cache add: name, spec, args [ undefined,
silly cache add: name, spec, args   'underscore.string@~2.0.0',
silly cache add: name, spec, args   [ 'underscore.string@~2.0.0', null ] ]
verbose parsed url { pathname: 'underscore.string@~2.0.0',
verbose parsed url   path: 'underscore.string@~2.0.0',
verbose parsed url   href: 'underscore.string@~2.0.0' }
silly cache add: name, spec, args [ 'underscore.string',
silly cache add: name, spec, args   '~2.0.0',
silly cache add: name, spec, args   [ 'underscore.string', '~2.0.0' ] ]
verbose parsed url { pathname: '~2.0.0', path: '~2.0.0', href: '~2.0.0' }
verbose addNamed [ 'underscore.string', '~2.0.0' ]
verbose addNamed [ null, '>=2.0.0- <2.1.0-' ]
silly name, range, hasData [ 'underscore.string', '>=2.0.0- <2.1.0-', false ]
verbose raw, before any munging underscore.string
verbose url resolving [ 'https://registry.npmjs.org/', './underscore.string' ]
verbose url resolved https://registry.npmjs.org/underscore.string
http GET https://registry.npmjs.org/underscore.string
ERR! Error: failed to fetch from registry: underscore.string
ERR!     at /usr/local/lib/node_modules/npm/lib/utils/npm-registry-client/get.js:139:12
ERR!     at cb (/usr/local/lib/node_modules/npm/lib/utils/npm-registry-client/request.js:32:9)
ERR!     at Request._callback (/usr/local/lib/node_modules/npm/lib/utils/npm-registry-client/request.js:137:18)
ERR!     at Request.callback (/usr/local/lib/node_modules/npm/node_modules/request/main.js:109:22)
ERR!     at Request.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/main.js:198:58)
ERR!     at Request.emit (events.js:88:20)
ERR!     at ClientRequest.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/main.js:195:10)
ERR!     at ClientRequest.emit (events.js:67:17)
ERR!     at CleartextStream.<anonymous> (http.js:1134:11)
ERR!     at CleartextStream.emit (events.js:67:17)
ERR! You may report this log at:
ERR!     <http://github.com/isaacs/npm/issues>
ERR! or email it to:
ERR!     <[email protected]>
ERR! 
ERR! System Linux 2.6.32-33-generic
ERR! command "node" "/usr/local/bin/npm" "install" "underscore.string"
ERR! cwd /mnt/hgfs/oss/sum.js/text-summarization
ERR! node -v v0.6.10
ERR! npm -v 1.1.0-3
ERR! message failed to fetch from registry: underscore.string
verbose exit [ 1, true ]

underscore.string doesn't mix in nicely with underscore.js in Node.js

I'm not sure what the best way to solve this is, but this has been driving me bonkers...the problem is the check at the top of underscore.string for the _ variable doesn't actually work reliably. Here's the test case:

var _ = require("underscore")
function Cat(){}
function Dog(){}
var cat = new Cat;
var dog = new Dog;
var animalsThatPurr = [cat];
console.log("Do dogs purr? " + _.include(animalsThatPurr, dog)); // prints false
_.mixin(require("underscore.string"));
console.log("Do they purr after including underscore.string? " + _.include(animalsThatPurr, dog)); // prints true

The problem is when underscore.string loads, _ will be undefined (since _ is scoped to the test file), so _.include (which was taken over by underscore.string) will fall back on to _.includes (also defined by underscore.string), which converts all/some of its args to strings, so you get a bunch of stringwise [Object object] comparisons.

Update version in object

If you log the object you get:

{ VERSION: '1.2.0',
  isBlank: [Function],
  stripTags: [Function],
  ...

format sentence

Hey -- great addition to Underscore; thanks :)

I just wrote a function that you might like to include; it's to take an array like ["John", "Paul", "George", "Ringo"] and format it with the syntax:

"John, Paul, George and Ringo."

It can take an array of strings or a JSON array and an iterator function to format them. There's a "max" parameter to limit the # of items used in the returned sentence.

Hope it's useful!

http://pastebin.com/CREV2a0k

chop problem

Negative parm:

_.chop("some text",-1);

will produce an infinite loop.

#titleize fails if string contain two spaces

Process:

> _.titleize('two words');
'Two Words'
> _.titleize('two  words');
TypeError: Object Two Words has no method 'titleize'
    at [object Context]:1:3
    at Interface. (repl:96:19)
    at Interface.emit (events:27:15)
    at Interface._ttyWrite (readline:309:12)
    at Interface.write (readline:147:30)
    at Stream. (repl:79:9)
    at Stream.emit (events:27:15)
    at IOWatcher.callback (net:489:16)
    at node.js:773:9

dasherize & Consecutive Capital Letters: Unexpected Behavior?

This may or may not be expected behavior, however neither the documentation nor the current test cases cover this.

Example code:

_('thisIsATest').dasherize();

What I expect to get: this-is-a-test
What I actually get: this-is-atest

Because of this, you also end up with this outcome:

var foo = 'thisIsATest';
_(foo).chain().dasherize().camelize().value() === foo;  // is false

Basically, is the current behavior the expected behavior, or is this an overlooked edge case?

Default String method

We would like to add a default string method, which would return a default string for string values that are null, undefined or empty.

Example:

_('').defaultString('Test') => 'Test'
_(null).defaultString('Test') => 'Test'
_('Some String').defaultString('Test') => 'Some String'

Get rid of sArgs

Cause it's freaking slow.

I guess the best way is to put something like str=str+'' every time we need to ensure argument is a String.

update npm version

Hello there
Thanks for this project, it's super useful
I would like to use underscore.string with node too, but it looks like the version published is not up to date.
Could you push the last version ?

error due to "use strict"

I am getting following error while trying out this simple html

Uncaught TypeError: Cannot read property '_' of undefined (underscore.string:325)
<!DOCTYPE html>
<html>
  <head>
    <title>Underscore String Test</title>
    <script src="/assets/underscore.js" type="text/javascript"></script>
    <script src="/assets/underscore.string.js" type="text/javascript"></script>
  </head>
  <body></body>
</html>

It appears to be because of "use strict". If I comment that out, everything works fine. I am getting this error on FF Aurora as well as Chrome Dev Channel on Mac. Apparently, "use strict" is not allowing direct access to window object. So "root = this" is interpreted undefined instead of window object within the browser.

Thanks for any help here.

please tag versions

Going forward it would be helpful if you could tag versions when they are created (and documented) in github, basically like underscore.js already does. It helps with tracking what version a developer has and ensuring we are in sync with online documentation. Also, I personally made the initial mistake of just grabbing 1.0.0 because it was the last tagged version. Thanks!

Problem with truncate

When using _('Hello').truncate(10) like in the example, I get the output "Hello..."

Cycle function

I'm interested in submitting a function that cycles through given arguments every time it is called with the same values. This can be used, for example, to alternate classes for table rows. Passing different arguments replaces previous cycle with a new cycle. Passing no arguments resets the cycle.

_.cycle('odd', 'even')
=> 'odd'
_.cycle('odd', 'even')
=> 'even'
_.cycle('odd', 'even')
=> 'odd'
_.cycle('one', 2, 'three')
=> 'one'
_.cycle('one', 2, 'three')
=> 2
_.cycle()
=> false
_.cycle('one', 2, 'three')
=> 'one'

I can submit a pull request if you're interested. Cheers.

Problems with numbers in IE6

There is an issue in IE6 when working with numbers. Example: _.trim("123") works fine, but _.trim(123) throws an error. The reason for this seems to be that IE6 doesn't automatically convert numbers to strings and thus all the String methods like replace() are missing.

A solution I found is to change each input str to str.toString(). However – and this is why I haven't created a commit yet – this needs many changes in many places. Now my questions would be:

  • Is there a simpler solution?
  • Is there a performance impact in doing .toString() everywhere?
  • Is it worth it?

In the business environment I'm using underscore.string in at the moment, IE6 is unfortunately still a reality, so my vote goes to "change it", even though I have solved my immediate problems with using .toString() in the place I need it. I could lend a hand with that. What do you think?

prune fails in IE8

The prune method is failing in IE8. Here's my hack-fix that I added to my local copy - but there is probably a more elegant way to address this:

str = _s.chars(str);
for(i in str) {...}
str = str.join('');

Thanks!

count doesn't work

_.str.count('x.xx....x.x','x') reports 3

The following works for me:

      str = ''+str; substr = ''+substr;
      var count = 0, index;
      for (var i=0; i < str.length;) {
        index = str.indexOf(substr, i);
        if (index<0) break;
        count++;
        i = index + substr.length;
      }
      return count;
    },

node / common.js module (and package.json)

changing the bottom of underscore.strings.js to:

  // Integrate with Underscore.js
    if (root._) {
        root._.mixin(root._s);
    }

  // Export for Node.js use
    else if (module) {
        module.exports = root._s;
    }

... makes this https://gist.github.com/742422 possible

Ideally, there would also be a package.json so it could be installed with npm. Underscore is already available this way. In the meantime, being able to copy / paste the raw code (without editing) is still a welcome convenience...

"difference" bug following mixin of underscore.string

I'm using the latest version of underscore and underscore.string:

var _ = require('underscore')

_.difference([ 1, 2, 'c' ], [ 1, 2, 'cc' ]) // => [ 'c' ]
_.difference([ 1, 2, 'cc' ], [ 1, 2, 'c' ]) // => [ 'cc' ]

Suppose I ...

_.mixin(require('underscore.string'))

Now I'm seeing the following "bug" with _.difference:

_.difference([ 1, 2, 'c' ], [ 1, 2, 'cc' ]) // => [ ] // empty array! BUT should be [ 'c' ]
_.difference([ 1, 2, 'cc' ], [ 1, 2, 'c' ]) // => [ 'cc' ]

So underscore.string is altering the behavior of _.difference. It took me some time to figure out this was happening as it's subtle.

tokenize, string-join

Maybe I'm missing something, are these functions included?
They are some of the most useful string functions out there:

["a", "b", "c"].string-join("; ")

"a; b; c"
"a; b; c".tokenize("; ")
["a", "b", "c"]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.