I just tried this code in Chrome deveoper tools:
var str = "1111111";
str[0] = 2;
2
console.log(str[0]);
1
As you can see, the output was 1, where I expected 2. My conclusion is this is not meant to be working like that, so I ask how would I get this to work - how would I change the first 'item' of the varable str to 2?
That is because in JavaScript strings are immutable objects. You should use substr function:
String.prototype.replaceAt = function (index, char) {
return this.substr(0, index) + char + this.substr(index + char.length);
};
var str = '11111';
console.log(str.replaceAt(0, '2'));
From the rhino book:
In JavaScript, strings are immutable objects, which means that the characters within them may not be changed and that any operations on strings actually create new strings. Strings are assigned by reference, not by value. In general, when an object is assigned by reference, a change made to the object through one reference will be visible through all other references to the object. Because strings cannot be changed, however, you can have multiple references to a string object and not worry that the string value will change without your knowing it.
Try this out
str.replace(str.charAt(0), "2")
You need to split the string first.
So something like:
str = str.split('');
Then you can treat it as an array.
Related
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 5 years ago.
I have an array
fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}
it contains simple and nested objects as items
i can reference f1 using bracket notation like fruit[0]["dry"]["f1"]
but i have a string variable that has the value var str="dry.f1"
value of "str" changes on runtime it could be "sweet" or "dry.f1" or "sour"
how do i reference the array item using "str"
if the value of str is either "sweet" or "sour" fruit[str] works fine
we can get the value of f1 using fruit[0].dry.f1 but i need to access it using the variable str
You can use split and reduce:
var fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'};
var str1 = "dry.f1";
var str2 = "sweet";
var example1 = str1.split('.').reduce((a, b) => a[b], fruit);
var example2 = str2.split('.').reduce((a, b) => a[b], fruit);
console.log(example1);
console.log(example2);
This will split your string on each dot into an array, and then reduce the fruit array by iterating through the values from the string, applying them to the fruit array, to get the value you are looking for.
Given array:
fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}
And your string:
var str="dry.f1"
To lookup value fruit.dry.f1 you essentially need to write a parser for "dry.f1"
There are plenty of libraries out there that solve this. I give an example below.
AngularJS
Examples of such parsers exist e.g. angular 1.x's $parse: https://docs.angularjs.org/api/ng/service/$parse
var getter = $parse('dry.f1');
var setter = getter.assign;
var context = {sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}
expect(getter(context)).toEqual('raisin');
Lodash
Lodash has a get method: https://lodash.com/docs/4.17.4#get
You could make a conditional, if statement that checks if the string has a dot using str.indexOf('.') and do either
fruit[str]
Or
fruit[str1][str2]
In order to access a value in an object given it's path, we must write a function that searches for that value path inside of the object.
Using split and reduce, we use split to break the path into an array of values that were dot-separated in the path (i.e. "dry.f1" becomes ["dry", "f1"]). We then use reduce to iterate over these values in the array, getting deeper into the object in each iteration until we have our value:
function findValueByPath(obj, path) {
return path.split(".").reduce(function(objSoFar, currPath) {
return objSoFar[currPath];
}, obj);
}
For example, findValueByPath( {a: { b: 5 } } , "a.b") returns 5.
Click here to read more about reduce.
Click here to read more about split.
As a side note, this problem is commonly implemented by libraries such as Lodash, which has the function get that does exactly this (click here for get documentation in Lodash).
Say I have an array with string values such as:
var foo = ["Hello", "World"];
I can return the first character of each array element by doing:
foo[0][0]; // Will return "H"
foo[1][0]; // Will return "W"
However, when attempting to change the value of those characters using a similar method, it doesn't work. What I mean is that doing this does not work:
foo[0][0] = "J"; // Will not change "H" to "J".
It's not a huge issue since I know alternative ways to do so such as:
foo[0] = "J"+foo[0].substsring(1); // Hello --> Jello
But I'm curious as to why the previous method does not work? EDIT: Did some fiddling around and apparently it doesn't work with strings at all to begin with, not just strings in arrays. I guess I was under the false impression that strings act just like arrays. I can return certain characters by calling it's position in the string similar to how calling an array index works, but changing said index doesn't hold.
From Javascript String reference:
For character access using bracket notation, attempting to delete or
assign a value to these properties will not succeed. The properties
involved are neither writable nor configurable. (See
Object.defineProperty() for more information.)
Strings are immutable, that is, they cannot be altered.
This:
foo[0][0] = "J";
Doesn't work because you are attempting to modify the string stored at position 0 in the foo array.
This:
foo[0] = "J"+foo[0].substsring(1);
does work because you aren't trying to modify a string, you are trying to replace the element at position 0 in the foo array with an entirely new string.
All primitive data types in JavaScript are immutable.
Quote from MDN:
Unlike in languages like C, JavaScript strings are immutable. This means that once a string is created, it is not possible to modify it. However, it is still possible to create another string based on an operation on the original string.
Strings are immutable, so they cannot be changed unless you create a new string and store the new value inside of that string. You cannot change a character within a string, The string manipulation methods such as trim, substring etc.
From substring method - The result is a String value, not a String object.
var foo = ["Hello", "World"];
foo[0][0] = "J";
console.log(foo);
foo[0] = "J"+foo[0].substring(1);
console.log(foo);
Notice if you change
var foo = [1, "World"];
foo[0][0] = "J";
It works, since it's not a string
Check this out : https://tc39.github.io/ecma262/#sec-string.prototype.substring
If start is larger than end, they are swapped.
The following steps are taken: From the link above
Let O be ? RequireObjectCoercible(this value).
Let S be ? ToString(O).
Let len be the number of elements in S.
Let intStart be ? ToInteger(start).
If end is undefined, let intEnd be len; else let intEnd be ? ToInteger(end).
Let finalStart be min(max(intStart, 0), len).
Let finalEnd be min(max(intEnd, 0), len).
Let from be min(finalStart, finalEnd).
Let to be max(finalStart, finalEnd).
Return a String whose length is to - from, containing code units from S, namely the code units with indices from through to - 1, in ascending order.
I'm trying to figure out why I cannot assign the toUpperCase method to a specific value in an array (see below). I am a little confused because I thought objects were mutable and manipulated by reference? Maybe I am looking at it backwards?
var ary = ["hello", "there", "world"];
ary[0][0] = ary[0][0].toUpperCase();
console.log(ary[0][0]); // returns lowercase h
Any clarification would help me out a lot.
Since Strings are immutable in JavaScript, assigning a new character to an index of a String will not change the string at all. You need to create a new String like this
ary[0] = ary[0][0].toUpperCase() + ary[0].substr(1);
# H
We are creating a new string with the first letter capitalized and the rest of the string as it is.
i want to remove array element, but giving error while using splice,
i m using following function
with myAra as global var,
but in console ,it is giving me an error, TypeError: myAra.splice is not a function
var myAra = Array();
function charCounts(e,textAreaId)
{
myAra = $("#"+textAreaId).val();
var countNewLines = stringOccurrences(myAra, "\n");
if(myAra.length>75)
{
for (var i = 75; i >myAra.length; i++)
{
myAra.splice(i, 1);
}
$("#"+textAreaId).val(myAra);
}
}
myAra is a String, not an Array, at the point when you call splice. It has the value of the element.
This is a nice example of why globals are EVIL, sure you declared the variable an array (badly): var myAra = Array() (I'll explain at the end what's bad about this), but later on:
myAra = $("#"+textAreaId).val();//returns a string, variable is now a string, not an array
You've reassigned a string to the array, so the variable now references a string constant, and cannot be used as an Array (not safely, in a X-browser way at least).
Array() is bad, why? Well, for starters, you're calling a constructor, but you're not using the new keyword. With arrays that's not a big problem (it'll return a new instance all the same), but when you start defining your own objects, and constructors, you'll find yourself up to your neck in globals. Also, suppose you wanted an array and initialize the first element to an int: var anArray = new Array(2);, you won't get an array that looks like this: anArray[0] === 2, you'll get anArray === [undefined,undefined]. Compare that to var anArray('2') --> ['2']. Given the fact that JS is loosely typed, and you'll often use variables when initializing an array, it's hard to tell weather or not you're passing a numeric string or a number to the constructor. The best way to initialize arrays is by using the literal notation: [2,3,4], as an added bonus, it requires less typing, too
Replace the following:
if(myAra.length>75)
{
for (var i = 75; i >myAra.length; i++)
{
myAra.splice(i, 1);
}
$("#"+textAreaId).val(myAra);
}
with the below code:
if(myAra.length>75)
{
var moreNum = myAra.length - 75;
myAra.splice(75, moreNum ); // remove all items after the 75th item
$("#"+textAreaId).val(myAra);
}
Note - splice change the actual array, that's why the loop was failing. Hope it helps.
You are assigning a string value directly to the myAra so it will convert it to string ..typeOf myAra. Use myAra[0]=$("#"+textAreaId).val();...since javascript is a loosely coupled language
In the first line you used var myAra = Array(), but the jQuery val() function returns a string.
EDIT: Also I think the prefered way of creating arrays in JS is the var myArray = [], and not using the var myArray = new Array() expression.
I've searched here: http://w3schools.com/jsref/default.asp but could not find any convenience method to perform this function. If I have an array var arrayOfStrings = ["20","10","30","100"], is there a quick way to remove all quotes (") from each string in this array without having to loop through?
I essentially want to create this: var arrayOfNumbers = [20,10,30,100]
Thanks
If you want number conversion, you can do it like this...
var arrayOfNumbers = arrayOfStrings.map(Number);
The .map() method creates a new array populated with the return value of the function you provide.
Since the built-in Number function takes the first argument given and converts it to a primitive number, it's very usable as the callback for .map(). Note that it will interpret hexadecimal notation as a valid number.
Another built-in function that would accomplish the same thing as the callback is parseFloat.
var arrayOfNumbers = arrayOfStrings.map(parseFloat)
The parseInt function however will not work since .map() also passes the current index of each member to the callback, and parseInt will try to use that number as the radix parameter.
MDN Array.prototype.map (includes compatibility patch)
DEMO: http://jsfiddle.net/UDWvH/
[
20,
10,
30,
100
]
You could try like this:
for(var i = 0; i < myArray.length; i++)
{
myArray[i] = parseInt(myArray[i], 10);
}
Have a look to the parseInt function.
For browsers that support JSON.parse:
var arr = ["20","10","30","100"];
var newArr = JSON.parse("[" + arr.join() + "]");
console.log(typeof arr[0]); //string
console.log(typeof newArr[0]); //number
You do not need to do anything, the double quotes in JavaScript are identifiers that state that the data within them is a string. This means they are not part of the array or data itself.
You can loop using a standard For loop.