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

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()

Related

Why doesn't my function correctly replace when using some regex pattern

This is an extension of this SO question
I made a function to see if i can correctly format any number. The answers below work on tools like https://regex101.com and https://regexr.com/, but not within my function(tried in node and browser):
const
const format = (num, regex) => String(num).replace(regex, '$1')
Basically given any whole number, it should not exceed 15 significant digits. Given any decimal, it should not exceed 2 decimal points.
so...
Now
format(0.12345678901234567890, /^\d{1,13}(\.\d{1,2}|\d{0,2})$/)
returns 0.123456789012345678 instead of 0.123456789012345
but
format(0.123456789012345,/^-?(\d*\.?\d{0,2}).*/)
returns number formatted to 2 deimal points as expected.
Let me try to explain what's going on.
For the given input 0.12345678901234567890 and the regex /^\d{1,13}(\.\d{1,2}|\d{0,2})$/, let's go step by step and see what's happening.
^\d{1,13} Does indeed match the start of the string 0
(\. Now you've opened a new group, and it does match .
\d{1,2} It does find the digits 1 and 2
|\d{0,2} So this part is skipped
) So this is the end of your capture group.
$ This indicates the end of the string, but it won't match, because you've still got 345678901234567890 remaining.
Javascript returns the whole string because the match failed in the end.
Let's try removing $ at the end, to become /^\d{1,13}(\.\d{1,2}|\d{0,2})/
You'd get back ".12345678901234567890". This generates a couple of questions.
Why did the preceding 0 get removed?
Because it was not part of your matching group, enclosed with ().
Why did we not get only two decimal places, i.e. .12?
Remember that you're doing a replace. Which means that by default, the original string will be kept in place, only the parts that match will get replaced. Since 345678901234567890 was not part of the match, it was left intact. The only part that matched was 0.12.
Answer to title question: your function doesn't replace, because there's nothing to replace - the regex doesn't match anything in the string. csb's answer explains that in all details.
But that's perhaps not the answer you really need.
Now, it seems like you have an XY problem. You ask why your call to .replace() doesn't work, but .replace() is definitely not a function you should use. Role of .replace() is replacing parts of string, while you actually want to create a different string. Moreover, in the comments you suggest that your formatting is not only for presenting data to user, but you also intend to use it in some further computation. You also mention cryptocurriencies.
Let's cope with these problems one-by-one.
What to do instead of replace?
Well, just produce the string you need instead of replacing something in the string you don't like. There are some edge cases. Instead of writing all-in-one regex, just handle them one-by-one.
The following code is definitely not best possible, but it's main aim is to be simple and show exactly what is going on.
function format(n) {
const max_significant_digits = 15;
const max_precision = 2;
let digits_before_decimal_point;
if (n < 0) {
// Don't count minus sign.
digits_before_decimal_point = n.toFixed(0).length - 1;
} else {
digits_before_decimal_point = n.toFixed(0).length;
}
if (digits_before_decimal_point > max_significant_digits) {
throw new Error('No good representation for this number');
}
const available_significant_digits_for_precision =
Math.max(0, max_significant_digits - digits_before_decimal_point);
const effective_max_precision =
Math.min(max_precision, available_significant_digits_for_precision);
const with_trailing_zeroes = n.toFixed(effective_max_precision);
// I want to keep the string and change just matching part,
// so here .replace() is a proper method to use.
const withouth_trailing_zeroes = with_trailing_zeroes.replace(/\.?0*$/, '');
return withouth_trailing_zeroes;
}
So, you got the number formatted the way you want. What now?
What can you use this string for?
Well, you can display it to the user. And that's mostly it. The value was rounded to (1) represent it in a different base and (2) fit in limited precision, so it's pretty much useless for any computation. And, BTW, why would you convert it to String in the first place, if what you want is a number?
Was the value you are trying to print ever useful in the first place?
Well, that's the most serious question here. Because, you know, floating point numbers are tricky. And they are absolutely abysmal for representing money. So, most likely the number you are trying to format is already a wrong number.
What to use instead?
Fixed-point arithmetic is the most obvious answer. Works most of the time. However, it's pretty tricky in JS, where number may slip into floating-point representation almost any time. So, it's better to use decimal arithmetic library. Optionally, switch to a language that has built-in bignums and decimals, like Python.

Grab multiple numbers 1-10 from string

I am parsing a string of multiple numbers between 1 and 10 with the eventual goal of adding them to a set.
There will be multiple concatenated numbers after a text identifier such as {text}12345678910.
I am currently using match(/\d/g) to grab the numbers but it separates 1 and 0 in 10. I then look for 0 in my String Array, see if there's a 1 in the element before it, turn it into a 10 and delete the other entry. Not very elegant.
How can I clean up my matching code? I definitely don't need to use regex for this, but it makes grabbing the numbers fairly easy.
You could just match with this regex:
/10|\d/g
(instead of the one you use currently, not additionally)
Regex is executed left-to-right, so first it finds any occurrences of 10, and then of other digits (so using, for example /\d|10/g or even /\d|(10)/g won't work either).

Getting the numeric value after the hyphen in a string

How can I extract and get just the numeric value after the hyphen in a string?
Here is the input string:
var x = "-2147467259"
After some processing.... return:
alert(2147467259)
How do I accomplish this?
You could replace away the hyphen:
alert(+x.replace("-", ""));
And yes, the + is important. It converts a string to a number; so you're removing the hypen by replacing it with nothing, and then essentially casting the result of that operation into a number. This operation will also work if no hyphen is present.
You could also use substr to achieve this:
alert(+x.substr(1));
You could also use parseInt to convert the string to a number (which will end up negative if a hyphen is persent), and then find its absolute value:
alert(Math.abs(parseInt(x, 10));
As Bergi notes, if you can be sure that the first character in the string is always a hyphen, you can simple return its negative, which will by default cast the value into a number and then perform the negative operation on it:
alert(-x);
You could also check to see if the number is negative or positive via a tertiary operator and then perform the respective operation on it to ensure that it is a positive Number:
x = x >= 0 ? +x : -x;
This may be cheaper in terms of performance than using Math.abs, but the difference will be minuscule either way.
As you can see, there really are a variety of ways to achieve this. I'd recommend reading up on JavaScript string functions and number manipulation in general, as well as examining JavaScript's Math object to get a feel for what tools are available to you when you go to solve a problem.
How about:
Math.abs(parseInt("-2147467259"))
Or
"-2147467259".replace('-','')
or
"-2147467259".replace(/\-/,'')
#1 option is converting the string to numbers. The #2 approach is removing all - from the string and the #3 option even though it will not be necessary on this example uses Regular Expression but I wanted to show the possibility of using RegEx in replace situations.
If you need a number as the final value #1 is your choice if you need strings #2 is your choice.

How to substract 2 char in javascript to get a difference in ascii

alert('g' - 'a') is returning Not a Number. ('NAN').
But I expect, to get the difference between ascii as alert(103-97) => alert(6). Hence 6 to be output.
In C, int i = 'g' - 'a', will give i = 6.
How to achieve this subtraction of 2 characters in javascript? (easily without much effort as below)
alert("g".charCodeAt(0) - "a".charCodeAt(0)) is giving 6.
Application : I am using this in chess program.
The only practicable way to do as you want is the way you've already suggested:
alert('g'.charCodeAt(0) - 'a'.charCodeAt(0));
As you know, this will retrieve the ASCII character code from 0th element of the string in each case, and subtract the second from the first.
Unfortunately this is the only way to retrieve the ASCII code of a given character, though using a function would be somewhat simpler, though given the brevity/simplicity of the charCodeAt() solution not all that much so.
References:
String.charCodeAt().
JavaScript doesn't treat characters as numbers; they are single-character strings instead. So the subtract operator will be calculating Number('g') - Number('a').
You should do 'g'.charCodeAt(0) - 'a'.charCodeAt(0) (there is no better way, but you can wrap it in a function)
You can write yourself a custom function. Something like this:
function asciiDif(a,b) {
return a.charCodeAt(0) - b.charCodeAt(0);
}
And then:
alert(asciiDif('g','a'));

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

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)

Categories

Resources