I am looking at an underscore.js function to retrieve the values from an object and am curious to understand the reason the _.values function was created the way it was.
The function as is in underscore.js:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
I believe this would also work however:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = [];
for (var i = 0; i < length; i++) {
values.push(obj[keys[i]]);
}
return values;
};
What is the tradeoff between using function #1 vs. #2. Is it simply for performance or is there other things?
Thanks.
The first approach allows the JS runtime to immediately allocate the correct amount of memory.
Calling push() on an empty array will force the array to resize as it gets full, wasting time and memory.
Related
I have created three functions, that can make two separate arrays with the matching keys and the matching properties. I would like to use those two arrays to create a new object with all of the matching pairs. Below I included the functions I have so far.
I am a beginner in Javascript ( which is most likely already apparent) so if you can explain each step thoroughly and not get to complex I would greatly appreciate it.
function contains(array, obj_to_check){
for(var i = 0; i < array.length; i ++) {
if (array[i] == obj_to_check) {
return true;
}
}
}
function sharedKeys(obj1, obj2) {
var obj1Keys = Object.keys(obj1);
var obj2Keys = Object.keys(obj2);
var sharedArray = [];
for( var x = 0; x < obj1Keys.length; x++){
if (contains(obj2Keys, obj1Keys[x])){
sharedArray.push(obj1Keys[x]);
}
}
return sharedArray;
}
function sharedProperties(obj1, obj2) {
var obj1Props = [];
var obj2Props = [];
var propertiesArray = [];
for(var i in obj1)
obj1Props.push(obj1[i]);
for(var x in obj2)
obj2Props.push(obj2[x]);
for (var y = 0; y < obj1Props.length; y ++){
if(contains(obj1Props, obj2Props[y])){
propertiesArray.push(obj2Props[y])
}
}
return propertiesArray;
}
You are comparing two objects, not two values. The only way that your == comparison works here is if both of them refer to the same object. You need to check and see if every properties and fields of those two objects are equal. Besides, check this thread about comparison in JavaScript.
I'm trying to implement a duplicate method to the js Array prototype which concats a duplicate of the array to itself like so:
[11,22,3,34,5,26,7,8,9].duplicate(); // [11,22,3,34,5,26,7,8,9,11,22,3,34,5,26,7,8,9]
Here's what I have, but it causes the browser to crash:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var j = this.length;
for(var i = 0; i < this.length; i++) {
this[j] = this[i];
j++;
}
return this;
}
I'm trying to do this using native JS as practice for iterations and algorithms so I'm trying to avoid built-in methods, if possible, so that I can get a clearer understanding of how things are being moved around.
Any ideas on why it is crashing and how I can optimize it?
The code inside the loop changes the length of the array, so it will just keep growing and you will never reach the end of it. Get the initial length of the array in a variable and use in the loop condition. You can use that as offset for the target index also instead of another counter:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var len = this.length;
for (var i = 0; i < len; i++) {
this[len + i] = this[i];
}
return this;
}
The length of the array is increasing with each element added so you can not use this as a terminator. Try this.
var j = this.length;
for(var i = 0; i < j; i++) {
this[i+j] = this[i];
}
Here's simplest code
Array.prototype.duplicate = function () {
var array = this;
return array.concat(array);
};
Using Spread syntax;
In a method, this refers to the owner object.
Array.prototype.duplicate = function () {
return [...this, ...this]
};
let array = [1,2,3,4,5];
Array.prototype.duplicate = function () {
return [...this, ...this]
};
console.log(array.duplicate());
I’m looking to use arrays to create unique names for variables. I am not looking to store any calculated values in the arrays, but rather be able to declare variables using arrays to store the values. My attempts and research how to accomplish this leads me to think that it’s not even possible. I’d appreciate it if someone could let me know and if it is possible an answer/example on how to do it. I’ll post a simplified example on what I’m hoping to get working.
var indices = ["index01", "index02", "index03"];
var keys = ["key01", "key02", "key03"];
for (var index = 0; index < indices.length; index++)
{
for (var key = 0; key < keys.length; key++)
{
var indices[index]+keys[key] //Looking for var index01key01, var index01key02 etc...
}
}
Well, basic javascript variables are in the window scope, so try:
var indices = ["index01", "index02", "index03"];
var keys = ["key01", "key02", "key03"];
for (var index = 0; index < indices.length; index++)
{
for (var key = 0; key < keys.length; key++)
{
// you can now use the variable as window.index01key01, or just index01key01
window[indices[index]+keys[key]] = null;
}
}
UPDATED
I've got an object var myObject = {};
I build it using a key like so:
myObject[key] = {
name: ...
};
So imagine I have created three records:
myObject[13] = {...};
myObject[281] = {...};
myObject[76] = {...};
I now want to loop through the object as if it were an array.
var i,
length = myObject.length; // ?? Problem here 'cos it ain't an array
for (i = 0; i < length; i += 1) {
????
};
How can I refer to the three elements at ????? I don't know the numbers 13, 281 & 76, and myObject[0] is not going to find the first record.
Thanks.
You shouldn't be using an array if your keys aren't consecutive. Use an object instead:
var myObject = {};
To loop over an object's keys, you use the for..in syntax:
for (var key in myObject) {
var value = myObject[key];
}
To make your current code work, you'd have to loop over all of the keys and check to see if they have values:
for (var i = 0; i < myArray.length; i++) {
var value = myArray[i];
if (typeof value === 'undefined') continue;
console.log(key, ' -> ', value)
}
If you're using a modern JavaScript engine:
myArray.forEach(function(val, key) {
// val = the value
// key = the index
});
And that's it. To get its size (3, in this case)...
var size = myArray.reduce(function(prev) {
return ++prev;
}, 0);
If you want this to work in older browsers, you'll need to do something else. The easiest solution would probably be to implement something like this yourself:
for (var i = 0; i < myArray.length; i ++) {
var val = myArray[i];
if (typeof val !== "undefined") {
console.log(val);
}
}
To get its size, it's a similar endeavor (that you could combine with the above method if you're doing both):
var size = 0;
for (var i = 0; i < myArray.length; i ++) {
if (typeof myArray[i] !== "undefined")
size ++;
}
If you want to use forEach and reduce like the above, you'll need to find a shim (basically, you'll need to implement those functions yourself). I'd recommend the larger of the two forEach shims on this page and the reduce shim on this page, or use a library that shims them all.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Counting occurences of Javascript array elements
I have an array in javascript and for example the array is:
array(1,1,1,1,5,5,7,7);
If can some one please help me to understand how to count similar values,
And how to join similar values,
Thank you all and have a nice day.
var array = [1,1,1,1,5,5,7,7];
var count = 0;
var tempArray = array.sort();
var i;
var prevValue = null;
var joined = [];
for (i = 0; i < array.length; i++) {
if (tempArray[i] != prevValue) {
count++;
prevValue = tempArray[i];
joined.push(prevValue);
}
}
document.write(joined);
If you're looking to uniquely identify array contents:
Array.prototype.unique =
function() {
var a = [];
var l = this.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
// If this[i] is found later in the array
if (this[i] === this[j])
j = ++i;
}
a.push(this[i]);
}
return a;
};
var myArray = [1,1,1,1,5,5,7,7];
var uniquedMyArray = myArray.unique();
var valueCountsMyArray = [];
for (var i = 0; i < myArray.length; i++) {
if (valueCountsMyArray[myArray[i]])
valueCountsMyArray[myArray[i]]++;
else
valueCountsMyArray[myArray[i]] = 1;
}
I can suggest using underscore.js. The code you're looking for isn't hard to write, and would be a good learning experience. Once you've done that, underscore is fantastic convenience library that offers what you're looking for, and you don't have to maintain it. :)
The uniq function will give you a copy of your array without duplicates, and the size function will tell you how many values that contains (or just reference the .length property).
Here a solution to count how many time it contains a number.
var count = [];
for(var i=0; i<array.length; i++) {
count[array[i]]++;
}