Difficulty with object function - javascript

Write a function named "indexed_kvs" that doesn't take any parameters and returns a new key-value store containing the integers from 0 to 47 as values each stored at a key which is a string containing the digits of the integer. For example the key-value "0":0 will be in your returned key-value store (include both 0 and 47 in your list) (My code below)
function indexed_kvs(){
var d = (dict = []);
for (var i of Array(47).keys()) {
d = dict.push(i);
}
return d;
}
I keep on returning the input 47, instead of the keys and values ranging from 0 to 47. How can I fix this?

Just use a simple while loop and iterate from the end or use a for loop.
function indexed_kvs() {
var object = {},
i = 48;
while (i--) object[i] = i;
return object;
}
console.log(indexed_kvs());
A shorter approach by generating an array and then create an object of the array.
function indexed_kvs() {
return Object.assign({}, [...Array(48).keys()]);
}
console.log(indexed_kvs());

This should work for you.
function makeKeys() {
var d = {};
for (var i = 0; i < 48; i++) {
d[i] = i;
}
return d;
}
console.log(makeKeys())

Related

Javascript - nested loops and indexes

I am trying to build an array that should look like this :
[
[{"name":"Mercury","index":0}],
[{"name":"Mercury","index":1},{"name":"Venus","index":1}],
[{"name":"Mercury","index":2},{"name":"Venus","index":2},{"name":"Earth","index":2}],
...
]
Each element is the concatenation of the previous and a new object, and all the indexes get updated to the latest value (e.g. Mercury's index is 0, then 1, etc.).
I have tried to build this array using the following code :
var b = [];
var buffer = [];
var names = ["Mercury","Venus","Earth"]
for (k=0;k<3;k++){
// This array is necessary because with real data there are multiple elements for each k
var a = [{"name":names[k],"index":0}];
buffer = buffer.concat(a);
// This is where the index of all the elements currently in the
// buffer (should) get(s) updated to the current k
for (n=0;n<buffer.length;n++){
buffer[n].index = k;
}
// Add the buffer to the final array
b.push(buffer);
}
console.log(b);
The final array (b) printed out to the console has the right number of objects in each element, but all the indexes everywhere are equal to the last value of k (2).
I don't understand why this is happening, and don't know how to fix it.
This is happening because every object in the inner array is actually the exact same object as the one stored in the previous outer array's entries - you're only storing references to the object, not copies. When you update the index in the object you're updating it everywhere.
To resolve this, you need to create new objects in each inner iteration, or use an object copying function such as ES6's Object.assign, jQuery's $.extend or Underscore's _.clone.
Here's a version that uses the first approach, and also uses two nested .map calls to produce both the inner (variable length) arrays and the outer array:
var names = ["Mercury","Venus","Earth"];
var b = names.map(function(_, index, a) {
return a.slice(0, index + 1).map(function(name) {
return {name: name, index: index};
});
});
or in ES6:
var names = ["Mercury","Venus","Earth"];
var b = names.map((_, index, a) => a.slice(0, index + 1).map(name => ({name, index})));
Try this:
var names = ["Mercury","Venus","Earth"];
var result = [];
for (var i=0; i<names.length; i++){
var _temp = [];
for(var j=0; j<=i; j++){
_temp.push({
name: names[j],
index:i
});
}
result.push(_temp);
}
console.log(result)
try this simple script:
var b = [];
var names = ["Mercury","Venus","Earth"];
for(var pos = 0; pos < names.length; pos++) {
var current = [];
for(var x = 0; x < pos+1; x++) {
current.push({"name": names[x], "index": pos});
}
b.push(current);
}

Returning key/value pair in javascript

I am writing a javascript program, whhich requires to store the original value of array of numbers and the doubled values in a key/value pair. I am beginner in javascript. Here is the program:
var Num=[2,10,30,50,100];
var obj = {};
function my_arr(N)
{
original_num = N
return original_num;
}
function doubling(N_doubled)
{
doubled_number = my_arr(N_doubled);
return doubled_number * 2;
}
for(var i=0; i< Num.length; i++)
{
var original_value = my_arr(Num[i]);
console.log(original_value);
var doubled_value = doubling(Num[i]);
obj = {original_value : doubled_value};
console.log(obj);
}
The program reads the content of an array in a function, then, in another function, doubles the value.
My program produces the following output:
2
{ original_value: 4 }
10
{ original_value: 20 }
30
{ original_value: 60 }
50
{ original_value: 100 }
100
{ original_value: 200 }
The output which I am looking for is like this:
{2:4, 10:20,30:60,50:100, 100:200}
What's the mistake I am doing?
Thanks.
Your goal is to enrich the obj map with new properties in order to get {2:4, 10:20,30:60,50:100, 100:200}. But instead of doing that you're replacing the value of the obj variable with an object having only one property.
Change
obj = {original_value : doubled_value};
to
obj[original_value] = doubled_value;
And then, at the end of the loop, just log
console.log(obj);
Here's the complete loop code :
for(var i=0; i< Num.length; i++) {
var original_value = my_arr(Num[i]);
var doubled_value = doubling(original_value);
obj[original_value] = doubled_value;
}
console.log(obj);
You can't use an expression as a label in an Object literal, it doesn't get evaluated. Instead, switch to bracket notation.
var original_value = my_arr(Num[i]),
doubled_value = doubling(Num[i]);
obj = {}; // remove this line if you don't want object to be reset each iteration
obj[original_value] = doubled_value;
Or:
//Original array
var Num=[2,10,30,50,100];
//Object with original array keys with key double values
var obj = myFunc(Num);
//Print object
console.log(obj);
function myFunc(arr)
{
var obj = {};
for (var i in arr) obj[arr[i]] = arr[i] * 2;
return obj;
}

How to retrieve a dynamic variable from an object

I have a js object which looks like this:
var detailsArray = [
{a0 :1,
b0 :'A'},
{a1 :2,
b1 :'B'},
{a2 :3,
b2 :'C'},
{a3 :4,
b3 :'D'}];
This is how the object is created from the server side. On the client side I want to retrieve the value of all 'a's and add them to an array. The problem is that the variable name is changing depending on the index number. I have tried using underscore.js to do something like this:
var variableA = new Array();
for(var i = 0;i<detailsArray.length;i++){
var temp = 'a' + i;
variableA[i] = _.pluck(detailsArray,temp);
}
But this does not work. Can anyone tell how to get the values??
There is two ways for accessing properties of object in javascript : using the dot like you just done, or using the array syntax style.
var obj = {'a':5};
obj.a
obj['a']
So with your code, this would give this :
var variableA = new Array();
for(var i = 0;i<detailsArray.length;i++){
variableA[i] = detailsArray[i]['a' + i];
}
With underscore, you could do:
_.reduce(_.map(detailsArray, function(o, i) {
return o['a' + i];
}), function(a, b) {
return a + b;
});
And with native JS in newer browsers:
detailsArray.map(function(o, i) {
return o['a' + i];
}).reduce(function(a, b) {
return a + b;
});
You can also do it like that:
for (var i = 0; i < detailsArray.length; i++)
alert(eval("detailsArray[" + i + "].a" + i));
The code I provide will alert all the values corresponding to as in the json array, but obviously you can do whatever you want with the values obtained.
Here I am counting that all the keys will be of the kind a smth, but I suppose this is a safe assumption.
here's one possible implementation
var tmp = [];
for (var i = 0; i < detailsArray.length; i++) {
var obj = detailsArray[i]; // current object at index
for (var props in obj) { // iterate properties in current object
if (props.charAt() == "a") { // if starts with a....
tmp.push(obj[props]); // add value to array
break; // stop the property iteration and move to next object
}
}
}
console.log(tmp); // [1,2,3,4]

javascript array with numeric index without undefineds

suppose I do..
var arr = Array();
var i = 3333;
arr[i] = "something";
if you do a stringify of this array it will return a string with a whole bunch of undefined numeric entries for those entries whose index is less than 3333...
is there a way to make javascript not do this?
I know that I can use an object {} but I would rather not since I want to do array operations such as shift() etc which are not available for objects
If you create an array per the OP, it only has one member with a property name of "333" and a length of 334 because length is always set to be at least one greater than the highest index. e.g.
var a = new Array(1000);
has a length of 1000 and no members,
var a = [];
var a[999] = 'foo';
has a length of 1000 and one member with a property name of "999".
The speedy way to only get defined members is to use for..in:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var p in a) {
if (a.hasOwnProperty(p) && re.test(p)) {
s.push(a[p]);
}
}
return '' + s;
}
Note that the members may be returned out of order. If that is an issue, you can use a for loop instead, but it will be slower for very sparse arrays:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var i=0, iLen=a.length; i<iLen; i++) {
if (a.hasOwnProperty(i)) {
s.push(a[i]);
}
}
return '' + s;
}
In some older browsers, iterating over the array actually created the missing members, but I don't think that's in issue in modern browsers.
Please test the above thoroughly.
The literal representation of an array has to have all the items of the array, otherwise the 3334th item would not end up at index 3333.
You can replace all undefined values in the array with something else that you want to use as empty items:
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'undefined') arr[i] = '';
}
Another alternative would be to build your own stringify method, that would create assignments instead of an array literal. I.e. instead of a format like this:
[0,undefined,undefined,undefined,4,undefined,6,7,undefined,9]
your method would create something like:
(function(){
var result = [];
result[0] = 0;
result[4] = 4;
result[6] = 6;
result[7] = 7;
result[9] = 9;
return result;
}())
However, a format like that is of course not compatible with JSON, if that is what you need.

Hashmaps in javascript from integer keys

I am coding in javascript & I need HashMap type structure .
Normally when I need hashmaps , I would use associative arrays only (with strings as keys).
But this time I need integers as keys to hashmaps.
So if I try to store A[1000]=obj, 1001 sized array is created & A[1001] is put as obj.
Even if I try A["1000"]=obj , it still allocates 1001 spaces & fills them with undefined.
I dont want that as my keys could be very large ( around 1 mill).
I could use it as A["dummy1000"]=obj but I dont want to use this dirty method.
Anyway of doing it elegantly & with ease too ?
Doing A[1000] = 1 doesn't create an array with 1000 elements. It creates an array object whose length attribute is 1001, but this is only because the length attribute in JavaScript arrays is defined as the maximum index + 1.
The reason it works like this is so you can do for(var i = 0; i < A.length; i++).
I see you're confused about the allocation of the array. To you it looks like JavaScript has filled the elements with undefined - actually there isn't anything there, but if you try to access any element in an array that hasn't been defined you get undefined.
Create a hash code from the key, and use that as index. Make the hash code limited to a small range, so that you get a reasonably small array of buckets.
Something like:
function HashMap() {
// make an array of 256 buckets
this.buckets = [];
for (var i = 0; i < 256; i++) this.buckets.push([]);
}
HashMap.prototype.getHash = function(key) {
return key % 256;
}
HashMap.prototype.getBucket = function(key) {
return this.buckets[this.getHash(key)];
}
HashMap.prototype.getBucketItem = function(bucket, key) {
for (var i = 0; i < bucket.length; i++) {
if (bucket[i].key == key) return i:
}
return -1;
}
HashMap.prototype.setItem = function(key, value) {
var bucket = this.getBucket(key);
var index = this.getBucketItem(bucket, key);
if (index == -1) {
bucket.push({ key: key, value: value });
} else {
bucket[index].value = value;
}
}
HashMap.prototype.getItem = function(key) {
var bucket = this.getBucket(key);
var index = this.getBucketItem(bucket, key);
if (index == -1) {
return null;
} else {
return bucket[index].value;
}
}
Disclaimer: Code is not tested.

Categories

Resources