JavaScript drops Array Brackets in Object Key value pair - javascript

Hey guys I noticed something strange today with trying to set a key value pair in JavaScript. I know that The Key of an object is always 'stringified' so that the key value pair is always string: value, however something strange happened today when I tried this with an array. Example below:
var ob = {};
var a = [2,4];
ob[a] = 10;
console.log("this is ob ", ob);
Here I have tried adding the key [2,4] to map to 10. However, the console log returns the string 2,4 mapping to 10 instead of the string [2,4] mapping to 10. Does anyone know why this happens?

Using an object or an array as the property name, doesn't invoke JSON#stringify, but the object's toString method, which in arrays returns the array elements joined by a comma.
In the example I override the Array#toString method, and you can see that the resulting property name reflects that:
var ob = {};
var a = [2,4];
a.toString = function() { return 'cats' }; // override toString
ob[a] = 10;
console.log("this is ob ", ob);

Related

how to turn a string into a variable

Im trying to use a command for a chat program and i want to edit a variable with a command like !editvar variablehere value
so if it variablehere = '123' i want to turn '123' into just 123 or something like 'hello' into hello, in simple words im trying to make a string from a chat message into a variable name
ive tried parsing and string.raw and none worked
if(message.startsWith('keyeditvar')) {
console.log(message)
var bananasplit = message.split(' ');
var bananasplitted = json.parse(bananasplit)
console.log(bananasplitted[0].keyeditvar)
var variable = bananasplit[1]
console.log(variable)
var value = bananasplit[2]
console.log(value)
var variable2 = String.raw(variable)
console.log(variable2)
var value2 = String.raw(value)
console.log(value2)
}
i expected it to work ig
im trying to turn a string into a variable name
In Javascript, you don't usually dynamically define new variables with custom names in the current scope. While you can do it at the global scope, you cannot easily do it in the function or block scope without using tools that are generally not recommended (like eval()).
Instead, you use an object and you create properties on that object. You can use either a regular object and regular properties or you can use a Map object with some additional features.
For a regular object, you can do thing like this:
// define base object
let base = {};
// define two variables that contain variable name and value
let someName = "greeting";
let someValue = "hello";
// store those as a property on our base object
base[someName] = someValue;
console.log(base); // {greeting: "hello"}
Then, you can change the value:
someValue = "goodbye";
base[someName] = someValue;
console.log(base); // {greeting: "goodbye"}
Or, you can add another one:
let someOtherName = "salutation";
let someOtherValue = "Dear Mr. Green";
base[someOtherName] = someOtherValue;
console.log(base); // {greeting: "goodbye", salutation: "Dear Mr. Green"}
console.log(base.greeting) // "goodbye"
console.log(base[someName]); // "goodbye"
console.log(base.salutation) // "Dear Mr. Green"
console.log(Object.keys(base)) // ["greeting", "salutation"]
You can think of the Javascript object as a set of key/value pairs. The "key" is the property name and the value is the value. You can get an array of the keys with:
Object.keys(obj)
You set a key/value pair with:
obj[key] = value;
You get the value for a key with:
console.log(obj[key]);
You remove a key/value pair with:
delete obj[key]
With a plain Javascript object like this, the keys must all be strings (or easily converted to a string).
If you have non-string keys, you can use a Map object as it will take any object or primitive value as a key, but it uses get() and set() methods to set and get key/values rather than the assignment scheme of a plain object.
Please, next time put a clean code...
To convert a string to a number. You can use the function : Number(object)
So for example :
Number('123')
will return 123.
If the object value is not a correct number, it will return NaN.
So for example :
Number('hello')
will return NaN.

Why can't I invoke Array.prototype.map with Set object [duplicate]

This question already has answers here:
Is it possible to use array iteration methods on ES6 Set instances?
(2 answers)
Closed 6 years ago.
I want to get get unique characters from some string using ES6's Set.
So let's assume that we have string var str = 'abcdeaabc'; and create set of characters from this string:
var str = 'abcdeaadbc';
var chars = new Set(str);
Now we have the set of unique characters: abcd.
I was surprised that char set has forEach method and has no map method.
Set is iterable object, so why can't we use map function to iterate over set?
I tried to pass chars set and chars.values() SetIterator to Array.prototype.map this way:
Array.prototype.map.call(chars, function(element) {...});
Array.prototype.map.call(chars.values(), function(element) {...});
But every try failed.
For example, let's assume that we want to get unique symbols from string and return an array of them with preceding underscore. eg.: ['_a', '_b', '_c', '_d']
Here are my two solutions:
// First:
var result = Array.from(chars).map(function(c) {
return '_' + c;
});
// Second:
var result = [];
chars.forEach(function(c) {
this.push('_' + c);
}, result);
But is there a way of invoking Array.prototype's map function with Set context? And if no - why?
Array.prototype.map works on array-like types that have integer indexes and a length property. Set and Map are general iterable types, but they are not array-like, so Array.prototype methods will not work on them. e.g.
var s = new Set([1, 2, 3]);
s.length === undefined;
s[0] === undefined
The main approach is Array.from kind of like your solution, but one thing to note is that Array.from takes a mapFn as the second argument, so you can do
let results = Array.from(chars, c => `_${c}`);
for a nice and short map to convert an iterable to an array.
If you are desperate you can do like this
var str = 'abcdeaadbc';
var chars = new Set(str);
document.write("<pre>" + JSON.stringify([...chars].map(c => c+"up")) + "</pre>")
Because even if map is generic enough to work for arbitrary array-like objects, not all iterable objects are array-like.
map just gets the length property, and then iterates properties from 0 to length-1. That can't work with sets because they have a size instead of length, and they don't provide random access to its elements.
If you really want to use map, you will need to transform the set to an array, and then transform the result back to a set.
var newSet = new Set(Array.from(set).map(myFunc));
But there is no point in doing that, it would be better to use set operations only:
var newSet = new Set();
for(let val of set) newSet.add(myFunc(val));
Or maybe a self-invoked generator function:
var newSet = new Set(function*() {
for(let val of set) yield myFunc(val);
}());

Two Dimensional Array in Javascript Object

I want to create an Object that contains one or more two dimensional arrays in Javascript.
I tried it the following way (in this example I only try to add one two dimensional array):
var XSIZE = 8;
var YSIZE = 8;
var obj = {
field : new Array(XSIZE),
field[0] : new Array(YSIZE),
foo : 1,
bar : 100
}
Info:
- This gives me a strange error "missing : after property id" which does not seem to make much sense
- Unfortunately I didn't find examples showing how to do this so far by using google
- If I don't add field[0] ... for creating the 2nd array it works.
- changing the XSIZE and YSIZE to numbers like new Array(8)... doesn't work.
I would really appreciate if somebody could show me how to do it or explain why I cannot do this at all and need to use some other method.
Thanks a lot!
The error "missing : after property id" is because JavaScript sees the field part of field[0] and expects a colon before the value of that field. Instead it gets an open bracket so it complains.
You can't hard code an object definition that has its dimensions set up at run time. You have to build the object at run time as well. Like this perhaps
var XSIZE = 8;
var YSIZE = 8;
var obj = {
field : new Array(),
foo : 1,
bar : 100
}
for (var i = 0; i < XSIZE; i++) {
obj.field.push(new Array(YSIZE));
}
In object literal notation, the property names must be exactly that: property names. Firstly, field[0] isn't a property name. Secondly, the properties don't exist until the after the object defined, so you can't access properties until then.
What you should do is either set the array after the object is created:
var obj = {...}
obj.field[0] = [...];
or nest the array literals:
var obj = {
field: [ [...],
...
],
...
}
You don't need to worry about setting the array size when creating the array, as it will grow when you add elements.
You can only declare properties on the object being constructed that way; not on objects in another "level".
You could use a for loop instead:
for(var i = 0; i < XSIZE; i++) {
obj.field[i] = new Array(YSIZE);
}
Note that the YSIZE is not necessary since an empty array works just fine as well ([]).
You could get the two dimensional array as your obj property, without resorting to external procedures and keep everything internal to the object. Create your empty 'field' array 1st.
var obj = {
field:[],
foo:1,
bar:100
};
Now, create an object's method to create a two dimensional array off your initial dimensionless array. You can determine the length and the number of dimensions of multi dimension array as you wish at run time:
var obj = {
field:[],
multifield:function(x,y){for (var count=0;count<x;count++) {this.field[count]=new Array(y);}},
foo:1,
bar:100
};
You can then call the obj.multifield method entering whatever dimensions you decide:
obj.multifield(10,5); //-->create a 10x5 array in this case...
console.log(obj.field.length); // 10
console.log(obj.field[0].length); // 5

How to store objects in a array using javascript

i am developing extesnions for safari browswer. i want to store current active tab objects in a array as key. how to store multiple tab objects in a array.
i wrote following code.
**First scenario:
var obj = {};
obj1=new Object();
obj2=new Object();
obj3=new Object();
obj['cTab_'+obj1] = "This is object1";
obj['cTab_'+obj2] = "This is object2";
obj['cTab_'+obj3] = "This is object3";**
prblem is i am getting 3rd object value. how to get all the object values.
**Second scenario:
var arr = new Array();
cTabObj1 = new Object();
arr[cTabObj1] = 'This is cTabObj1 Value';
cTabObj2 = new Object();
arr[cTabObj2] = 'This is cTabObj2 Value';
cTabObj3 = new Object();
arr[cTabObj3] = 'This is cTabObj3 Value';
alert("arr[cTabObj1] :" + arr[cTabObj1] + " arr[cTabObj2] :" + arr[cTabObj2] + " arr[cTabObj3] :" + arr[cTabObj3]);**
Here also i am getting "This is cTabObj3 Value" for all three object
Thanks in advance.
i want to store current active tab objects in a array as key
You can't do that. Keys are strings. They always are strings.
If you take a look at the array you will find any object gets converted to "[object Object]" so your basically inserting the same key 3 times.
Use console.log(arr) or console.dir(arr) together with firebug or chrome/opera/safari
What you want is a ES6 WeakMap.
Only Firefox6 implements WeakMap
The keys need to be strings.
Try implementing the toString method on your objects so that it returns a unique identifier for each object. Then 'cTab_' + obj will be a unique string.
You should rather store like this
cTabObj1 = new Object();
arr["cTabObj1"] = cTabObj1;
Your first scenario is the way to go except that you have assigned the same subscript key to each object that you are storing in obj. When you use anything other than a string for an object property key, the value has toString() called on it internally, so
obj['cTab_'+obj1] = "This is object1";
obj['cTab_'+obj2] = "This is object2";
obj['cTab_'+obj3] = "This is object3";
will all have the same key of cTab_[object Object].
What you need is to differentiate the keys. Since each object will return "[object Object]" when toString() is called on it, you can remove the object from the property key too as it is redundant e.g.
var obj = {};
obj['cTab1'] = "This is object1";
obj['cTab2'] = "This is object2";
obj['cTab3'] = "This is object3";
or more tersely
var obj = {
cTab1 : "This is object1",
cTab2 : "This is object2",
cTab3 : "This is object3"
};
The reason why the second way is not the way to go is that you are trying to use a JavaScript array like an associative array, which they are not; it may seem to work at first but then you will discover some very odd behaviour, such as arr.length does not count them as items in the array, etc. For more details, read the linked article. You want to use Object ({}) for this.

JS & jQuery: inArray() and indexOf() are not working properly if indexes are strings?

I have an array like this:
var arr = [];
arr['A string'] = '123';
arr['Another string'] = '456';
and Im trying to find an index of '123' or '456'.
Both:
var string = $.inArray('123', arr)
and
var string = arr.indexOf('123')
are giving me -1. Is it possible to get it working when indexes are strings?
Like all Array methods and the length property, the indexOf method of an Array object only considers numeric properties of the Array. These are properties whose names are unsigned integers. To test for the existence of a property with a particular value, you can do something like this on any object, including arrays. There's no guarantee about the enumeration order of property names, so if there's more than one property with a particular value then you can't be sure which property you'll get:
function findPropertyWithValue(obj, val) {
for (var i in obj) {
if (obj.hasOwnProperty(i) && obj[i] === val) {
return i;
}
}
return null;
}
var arr = [];
arr['A string'] = '123';
arr['Another string'] = '456';
alert(findPropertyWithValue(arr, "123")); // 'A string'
Note that since all property names, including numeric ones, are converted into strings, you can assign array properties using strings:
var arr = [];
arr["1"] = "foo";
arr[3] = "bar"
arr.indexOf("foo"); // 1
arr.indexOf("bar"); // 3
The problem is that you are using a JavaScript array as an associative array, something that it is not. The indices of a JavaScript array are unsigned 32 bit integers and therefore you can't use *strings**. You would either use an array like so
// I'm guessing that you meant to give numerical and not string values
var arr = [123, 456];
or use an object
var obj = {
'A string' : 123,
'Another string' : 456
};
Note that using an object, 'A string' and 'Another string' are properties of object obj and can't be indexed like the values in an array. You can check that an object has a property a number of ways, one of which would be using hasOwnProperty
if (obj.hasOwnProperty('A string')) {
// if obj has property 'A string' as a direct property
}
another would be using the in keyword
if ('A string' in obj) {
// if obj has a property 'A string' as a property (could be an inherited property too)
}
**unless the string is the string representation of a 32 bit unsigned integer as Tim points out, but I think it's fair to say that a lot of JavaScript developers would say stick to using integers for clarity.*

Categories

Resources