What is the difference between String.slice and String.substring? - javascript

Does anyone know what the difference is between these two methods?
String.prototype.slice
String.prototype.substring

slice() works like substring() with a few different behaviors.
Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);
What they have in common:
If start equals stop: returns an empty string
If stop is omitted: extracts characters to the end of the string
If either argument is greater than the string's length, the string's length will be used instead.
Distinctions of substring():
If start > stop, then substring will swap those 2 arguments.
If either argument is negative or is NaN, it is treated as if it were 0.
Distinctions of slice():
If start > stop, slice() will return the empty string. ("")
If start is negative: sets char from the end of string, exactly like substr() in Firefox. This behavior is observed in both Firefox and IE.
If stop is negative: sets stop to: string.length – Math.abs(stop) (original value), except bounded at 0 (thus, Math.max(0, string.length + stop)) as covered in the ECMA specification.
Source: Rudimentary Art of Programming & Development: Javascript: substr() v.s. substring()

TL;DR:
If you know the index (the position) on which you'll stop (but NOT include), use slice().
If you know the length of characters to be extracted, you could use substr(), but that is discouraged as it is deprecated.
Otherwise, read on for a full comparison
Syntax
string.slice(start,end)
string.substr(start,length)
string.substring(start,end)
Note #1: slice()==substring()
What it does?
slice() extracts parts of a string and returns the extracted parts in a new string.
substr() extracts parts of a string, beginning at the character at the specified position, and returns the specified number of characters.
substring() extracts parts of a string and returns the extracted parts in a new string.
Note #2: slice()==substring()
Changes the Original String?
slice() doesn't
substr() doesn't
substring() doesn't
Note #3: slice()==substr()==substring()
Using Negative Numbers as an Argument
slice() selects characters starting from the end of the string
substr() selects characters starting from the end of the string
substring() doesn't perform
Note #4: slice()==substr()
If the First Argument is Greater than the Second
slice() doesn't perform
substr() since the Second Argument is NOT a position, but length value, it will perform as usual, with no problems
substring() will swap the two arguments, and perform as usual
The First Argument
slice() required; starting Index
substr() required; starting Index
substring() required; starting Index
Note #5: slice()==substr()==substring()
The Second Argument
slice() optional; the position (up to, but not including) where to end the extraction
substr() optional; the number of characters to extract
substring() optional; the position (up to, but not including) where to end the extraction
Note #6: slice()==substring()
What if the Second Argument is Omitted?
slice() selects all characters from the start-position to the end of the string
substr() selects all characters from the start-position to the end of the string
substring() selects all characters from the start-position to the end of the string
Note #7: slice()==substr()==substring()
So, you can say that there's a difference between slice() and substr(), while substring() is basically a copy of slice().
If you want substr's functionality:
"foobarbaz".substr(index, length);
without using a deprecated feature, you can just do:
"foobarbaz".substring(index, length + index);
And get the exact same results bar all of the edge-cases, like negative index/length.

Ben Nadel has written a good article about this, he points out the difference in the parameters to these functions:
String.slice( begin [, end ] )
String.substring( from [, to ] )
String.substr( start [, length ] )
He also points out that if the parameters to slice are negative, they reference the string from the end. Substring and substr doesn't.
Here is his article about this.

The one answer is fine but requires a little reading into. Especially with the new terminology "stop".
My Go -- organized by differences to make it useful in addition to the first answer by Daniel above:
1) negative indexes. Substring requires positive indexes and will set a negative index to 0. Slice's negative index means the position from the end of the string.
"1234".substring(-2, -1) == "1234".substring(0,0) == ""
"1234".slice(-2, -1) == "1234".slice(2, 3) == "3"
2) Swapping of indexes. Substring will reorder the indexes to make the first index less than or equal to the second index.
"1234".substring(3,2) == "1234".substring(2,3) == "3"
"1234".slice(3,2) == ""
--------------------------
General comment -- I find it weird that the second index is the position after the last character of the slice or substring. I would expect "1234".slice(2,2) to return "3". This makes Andy's confusion above justified -- I would expect "1234".slice(2, -1) to return "34". Yes, this means I'm new to Javascript. This means also this behavior:
"1234".slice(-2, -2) == "", "1234".slice(-2, -1) == "3", "1234".slice(-2, -0) == "" <-- you have to use length or omit the argument to get the 4.
"1234".slice(3, -2) == "", "1234".slice(3, -1) == "", "1234".slice(3, -0) == "" <-- same issue, but seems weirder.
My 2c.

The difference between substring and slice - is how they work with negative and overlooking lines abroad arguments:
substring(start, end)
Negative arguments are interpreted as zero. Too large values ​​are truncated to the length of the string:
alert("testme".substring(-2)); // "testme", -2 becomes 0
Furthermore, if start > end, the arguments are interchanged, i.e. plot line returns between the start and end:
alert("testme".substring(4, -1)); // "test"
// -1 Becomes 0 -> got substring (4, 0)
// 4> 0, so that the arguments are swapped -> substring (0, 4) = "test"
slice
Negative values ​​are measured from the end of the line:
alert("testme".slice(-2)); // "me", from the end position 2
alert("testme".slice(1, -1)); // "estm", from the first position to the one at the end.
It is much more convenient than the strange logic substring.
A negative value of the first parameter to substr supported in all browsers except IE8-.
If the choice of one of these three methods, for use in most situations - it will be slice: negative arguments and it maintains and operates most obvious.

substr: It's providing us to fetch part of the string based on specified index.
syntax of substr-
string.substr(start,end)
start - start index tells where the fetching start.
end - end index tells upto where string fetches. It's optional.
slice: It's providing to fetch part of the string based on the specified index. It's allows us to specify positive and index.
syntax of slice - string.slice(start,end)
start - start index tells where the fetching start.It's
end - end index tells upto where string fetches. It's optional.
In 'splice' both start and end index helps to take positive and negative index.
sample code for 'slice' in string
var str="Javascript";
console.log(str.slice(-5,-1));
output: crip
sample code for 'substring' in string
var str="Javascript";
console.log(str.substring(1,5));
output: avas
[*Note: negative indexing starts at the end of the string.]

The only difference between slice and substring method is of arguments
Both take two arguments e.g. start/from and end/to.
You cannot pass a negative value as first argument for substring method but for slice method to traverse it from end.
Slice method argument details:
Arguments
start_index
Index from where slice should begin. If value is provided in negative it means start from last. e.g. -1 for last character.
end_index
Index after end of slice. If not provided slice will be taken from start_index to end of string. In case of negative value index will be measured from end of string.
Substring method argument details:
Arguments
from
It should be a non negative integer to specify index from where sub-string should start.
to
An optional non negative integer to provide index before which sub-string should be finished.

For slice(start, stop), if stop is negative, stop will be set to:
string.length – Math.abs(stop)
rather than:
string.length – 1 – Math.abs(stop)

Related

Why slice(-x,0) doesn't produce expected string

If I have this:
console.log('12345'.slice(-3)); // I get '345'
but when I do:
console.log('12345'.slice(-3, 0)); // I get '' (empty string).
what is the reasoning behind this? It makes no sense to me. Is there a JS API that can wrap around strings like I expect here? (I was expecting '345' again.)
The second parameter is the index where the substring to be extracted ends (exclusive). If that index is before (or equal to) the start index (the first parameter), the result is the empty string.
As the docs say about the second parameter:
If end is positioned before or at start after normalization, nothing is extracted.
After normalization, .slice(-3) is equivalent to .slice(2), and the second parameter defaults to the length of the string, so
.slice(-3)
// equivalent to
.slice(2)
is like
.slice(2, 5) // take the substring from index 2 to index 5
and not
.slice(2, 0)

I need an explanation on slice()

I was completing javascript exercises and got stuck on creating a function which checks if a string is a palindrome. For your reference, this was the given solution.
I understand what slice() does as a method, and I followed the function here until the point where it checks to see if the first letter matches the last.
if (cstr[x] != cstr.slice(-1-x)[0])
What is going on with the parameter values of the slice method? I was expecting the parameters to slice the last letter and I presume it does but I would appreciate some help in pointing out how!
Let's pop open the console and take a look!
> var s = 'abcde'
"abcde"
> s[0]
"a"
> s.slice(-1)
"e"
> s.slice(-1)[0]
"e"
> s[1]
"b"
> s.slice(-1 - 1)
"de"
> s.slice(-1 - 1)[0]
"d"
As I hope you can see by now, slicing with a negative number -n will return the last n characters of the string, with n = 1 being the last character. So to have the palindrome test work correctly, you need to slice at -1 - x (the "x-th from last" character).
arr.slice([begin[, end]])
Parameters
begin
Zero-based index at which to begin extraction. As a negative index, begin indicates an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence. If begin is omitted, slice begins from index 0.
end
Zero-based index at which to end extraction. slice extracts up to but not including end. slice(1,4) extracts the second element up to the fourth element (elements indexed 1, 2, and 3). As a negative index, end indicates an offset from the end of the sequence. slice(2,-1) extracts the third element through the second-to-last element in the sequence. If end is omitted, slice extracts to the end of the sequence (arr.length).
Description
slice returns a shallow copy of elements from the original array. Elements of the original array are copied into the returned array as follows:
For object references (and not the actual object), slice copies object references into the new array. Both the original and new array refer to the same object. If a referenced object changes, the changes are visible to both the new and original arrays.
For strings and numbers (not String and Number objects), slice copies strings and numbers into the new array. Changes to the string or number in one array does not affect the other array.
If a new element is added to either array, the other array is not affected.

How to find a "(a substring)" in a given "text" without using Regular expressions?

Recently I was asked in an interview, where the interviewer asked me this above question.
I was surely perplexed and answered him by using a for loop implementation where
we would find the length of the given "text" (using JavaScript) ... str.length() ...
we would take the first element of the "pattern" and find that in the "text".
If found we would increment the array .. As strings are stored as array in JavaScript ..
And we would find the "(a substring)" in similar way..
know this might be wrong way , but can anyone suggest a better way ? Thank you :-)
String.prototype.search (regexp)
When the search method is called with argument regexp, the following steps are taken:
Call CheckObjectCoercible passing the this value as its argument.
Let string be the result of calling ToString, giving it the this value as its argument.
If Type(regexp) is Object and the value of the [[Class]] internal property of regexp is "RegExp", then let rx be regexp;
Else, let rx be a new RegExp object created as if by the expression new RegExp(regexp) where RegExp is the standard built-in constructor with that name.
Search the value string from its beginning for an occurrence of the regular expression pattern rx. Let result be a Number indicating the offset within string where the pattern matched, or –1 if there was no match. The lastIndex and global properties of regexp are ignored when performing the search. The lastIndex property of regexp is left unchanged.
Return result.
Or if you want to avoid the word RegExp alltogether and search for a sub-string then
String.prototype.indexOf (searchString, position)
If searchString appears as a substring of the result of converting this object to a String, at one or more positions that are greater than or equal to position, then the index of the smallest such position is returned; otherwise, ‑1 is returned. If position is undefined, 0 is assumed, so as to search all of the String.
The indexOf method takes two arguments, searchString and position, and performs the following steps:
Call CheckObjectCoercible passing the this value as its argument.
Let S be the result of calling ToString, giving it the this value as its argument.
Let searchStr be ToString(searchString).
Let pos be ToInteger(position). (If position is undefined, this step produces the value 0).
Let len be the number of characters in S.
Let start be min(max(pos, 0), len).
Let searchLen be the number of characters in searchStr.
Return the smallest possible integer k not smaller than start such that k+ searchLen is not greater than len, and for all nonnegative integers j less than searchLen, the character at position k+j of S is the same as the character at position j of searchStr; but if there is no such integer k, then return the value -1.
I think the answer depends on the context, and the context seems to be lacking.
If the question was about algorithms, then I believe your best choice of algorithms (i.e., the fastest algorithm) is Boyer–Moore string search.
If the question was a HowTo in PHP, then its probably string.indexOf. And str.search would probably not be a valid answer since it takes a regex.
S[i] refers to the character at index i of string S, counting from 1.
S[i..j] refers to the substring of string S starting at index i and ending at j, inclusive.
A prefix of S is a substring S[1..i] for some i in range [1, n], where n is the length of S.
A suffix of S is a substring S[i..n] for some i in range [1, n], where n is the length of S.
The string to be searched for is called the pattern and is referred to with symbol P.
The string being searched in is called the text and is referred to with symbol T.
The length of P is n.
The length of T is m.
An alignment of P to T is an index k in T such that the last character of P is aligned with index k of T.
A match or occurrence of P occurs at an alignment if P is equivalent to T[(k-n+1)..k].

What String.substr(negative number) does?

I found this snippet, but I am not sure if it should have -5 or -6, because I do not what exactly substr(negative) does.
('00000'+(15).toString(16)).substr(-5)
substr() returns the a string made up of the last N characters, when -N is passed to it.
"Hello".substr(-2) => "lo"
From the docs:
If start is negative, substr uses it as a character index from the end
of the string. If start is negative and abs(start) is larger than the
length of the string, substr uses 0 as the start index.
In general:
str.substr(-n)
Is the same as:
str.substr(str.length-n)
Which is the same as:
str.substr(str.length-n,str.length)
Which returns the sub-string:
str[str.length-n,...,str.length-1]

Why two different methods slice() & substring()?

var name="nameSomnath";//remove name
I can do with slice()
var result = name.slice( 4 );
Same can be done with substring()
var result = name.substring( 4 );
So what makes them different.
I have seen the link Here which elaborates the difference .But we can do the same thing by using any one method ie slice() or substring().So why there was need to have two methods.
Even though it looks superficially like slice and substring do the same thing, the big difference is in how they handle negative arguments.
When JavaScript was first created in Netscape 2.0, there was just a substring method. If either of its arguments are negative, they are treated as 0.
When JavaScript 1.2 was introduced with Netscape 4.0, they wanted to add the behavior of allowing negative indexes to mean distances from the end of the string. They couldn't change substring to have this new behavior because it would break backward compatibility with scripts that expected negative indexes to be treated as 0, so they had to create a new function to support the added feature. This function was called slice, and was implemented on Array as well as String.
Another, smaller difference is that with substring the order of the arguments doesn't matter, so substring(1, 4) is the same as substring(4, 1). With slice, order does matter, so slice(4, 1) will just yield an empty string.
One item that makes them different is the second parameter that you have omitted
slice: the second parameter is the end index (exclusive) of the range to take.
substr: the second parameter is the length of the string to take from the index specified with the first parameter
Can you completely replicate the behavior of one method with the other on string instances? Yes. Why they chose to include both is probably lost to history. My guess though would be familiarity. I bet there are very few frameworks out there which have slice for strings but plenty that have substr.
Edit:
Oooops - I was wrong - there IS a slice method for strings too! I will delete my post again - sorry for not researching properly!!! Or, well , may be not delete it, but leave this correction in it at least. ;-)
You are looking at two methods of different classes. substr can only be applied on String-objects while slice belongs to Array-objects. They might seem similar to yo, yet internally they work in different ways since the data they handle is different.
BTW, this is not a jQuery but a plain JavaScript question. ;-)
In slice the arguments are the first index and last index. In substr, the arguments are first index and length.
slice
.slice(start, end)
Does not include, the given end index element
substr
.substr(start,length)
Extracts from start position up to the no. of chars. specified
substring
.substring(start, end)
extracts the characters between the two specified indices
slice() and substring() do the same thing with some common behaviors, but there are some distinctions in the handling negative arguments
Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);
Common behaviors:
If start equals stop: returns an empty string
If the stop is omitted: extracts characters to the ethe nd of the string
If either argument is greater than the string's length, the string's
length will be used instead.
Distinctions of substring():
If start > stop, then substring will swap those 2 arguments.
If either argument is negative or is NaN, it is treated as if it
were 0.
Distinctions of slice():
If start > stop, slice() will return the empty string. ("")
If the start is negative: sets char from the end of the string, exactly
like substr() in Firefox. This behavior is observed in both Firefox
and IE.
If the stop is negative: sets stop to: string.length – Math.abs(stop)
(original value), except bounded at 0 (thus, Math.max(0,
string.length + stop)) as covered in the ECMA specification.
Source: Javascript: substr() v.s. substring()

Categories

Resources