Is it faster to loop through JavaScript objects with fewer properties? - javascript

If there are two object definitions and one of the objects has a lot more properties than the other -
Example objects:
var personObjectType1 =
{
name: [a string],
age: [an int]
};
var personObjectType2 =
{
name: [a string],
age: [an int],
address: [a string],
photo: [a link],
spouse: [a string],
cars: [an array of strings],
children: [an array of strings],
pets: [an array of strings],
father: [a string],
mother: [a string],
birthdate: [a date]
};
And you have an equal length array of each of those objects, will looping through the array of objects be faster for the objects with fewer properties?
(NOTE: The same action is being performed on each type of object)
Example code:
//personObjectType1Array is an array of 10000 personObjectType1's
//personObjectType2Array is an array of 10000 personObjectType2's
for (var i = 0; i < personObjectType1Array.length; i++)
{
console.log(personObjectType1Array[i].age);
}
for (var j = 0; j < personObjectType2Array.length; j++)
{
console.log(personObjectType2Array[i].age);
}
Would one loop run faster than the other? Why or why not?
EDIT:
Responses are saying that there is no difference, can anyone say why?

The performance is seems almost same with both the array
var personObjectType1Array = [];
var personObjectType2Array = [];
for(var i=0; i<10000; i++)
{
personObjectType1Array.push({
name: '[a string]',
age: 25
});
personObjectType2Array.push(
{
name: '[a string]',
age: 25,
address: '[a string]',
photo: '[a link]',
spouse: '[a string]',
cars: '[an array of strings]',
children: '[an array of strings]',
pets: '[an array of strings]',
father: '[a string]',
mother: '[a string]',
birthdate: '[a date]'
}
);
}
//personObjectType1Array is an array of 10000 personObjectType1's
//personObjectType2Array is an array of 10000 personObjectType2's
var startTimeArray1 = window.performance.now();
for (var i = 0; i < personObjectType1Array.length; i++)
{
//console.log(personObjectType1Array[i].age);
}
console.log('TimeArray1 : ' + (window.performance.now() - startTimeArray1));
var startTimeArray2 = window.performance.now();
for (var j = 0; j < personObjectType2Array.length; j++)
{
//console.log(personObjectType2Array[i].age);
}
console.log('TimeArray2 : ' + (window.performance.now() - startTimeArray2));
Here I have created a demo
https://jsbin.com/hurewod/edit?js,console

you can check time taken of both in console.Execution time of those having more property will be more.
var personObjectType1 =
{
name : 'xyz',
age : 12,
roll : 23,
code :29,
height :26,
address:{"streetNo":121,"City":"New Delhi"}
};
var personObjectType2 = {name : 'xyz'};
var t0 = performance.now();
for (var i = 0; i < personObjectType1.length; i++){
//console.log(personObjectType1[i].name);
}
var t1 = performance.now();
console.log("Call to personObjectType1 took " + (t1 - t0) + " milliseconds.")
var t2 = performance.now();
for (var j = 0; j < personObjectType2.length; j++){
//console.log(personObjectType2[j].name);
}
var t3 = performance.now();
console.log("Call to personObjectType2 took " + (t3 - t2) + " milliseconds.")

Probably because the code needs to be compiled the first time through. You'll get the best metrics by calling all methods first, then execute.
Incidentally, the difference in performance between loop will be negligible and the readability benefits of using loop have a marginal performance benefit.

Related

Find Smallest Number from javascript object

I have a form where the user enters their city, this then returns for all the cities where my client is based in a 30 mile radius. I am now trying to find the closest city out of these and return just one result with both City Name and Distance (in metres).
I have a for loop which processes my results:
for (var i = 0; i < origins.length; i++) {
var results = response.rows[i].elements;
//console.log(response);
for (var j = 0; j < results.length; j++) {
// If distance is less than 30 miles (48280 metres)
if(results[j].distance.value < 48280) {
var closestCitiesDist = results[j].distance.value
var closestCitiesName = origins[i]
var closestCities = {"cityName" : closestCitiesName, "cityDistance" : closestCitiesDist}
console.log(closestCities);
}
}
}
This now returns an array for each result, containing cityName and cityDistance variable. Out of each of these arrays, I would like to find the single closest city (the array with the smallest cityDistance), and be able to output "City xx is the closest (xxx metres away)"
You could use Array#sort which has a time complexity of O(n log n) or instead you could do a single backwards pass of bubble sort in O(n), to bring the smallest city to the front of the array.
const object = [
{ cityName: 'Vancouver', cityDistance: 3 },
{ cityName: 'Paris', cityDistance: 4 },
{ cityName: 'London', cityDistance: 1 },
];
for (let i = object.length - 1; i > 0; i--) {
if (object[i].cityDistance < object[i - 1].cityDistance) {
temp = object[i - 1];
object[i - 1] = object[i];
object[i] = temp;
}
}
console.log(
`City ${object[0].cityName} is the closest (${object[0].cityDistance} metres away)`
);
You use Array.prototype.sort() on an array of objects, and sort it as you wish
Reference Material: Array.prototype.sort
Here element at the 0 index will have the smalles value property
const object = [{ name: 'test', value: 3}, { name: 'test2', value: 1}];
const sorted = object.sort((a, b) => a.value - b.value);
console.log(sorted);

Need help correcting & combining two functions into one

The Question is
Create a function called divisibles() that will take each object in upper and find all
objects in lower that evenly divide into it, ignoring zero. The function should return an
object that is upper but each object has an additional key called found and the value
for that key is an array containing each item from lower that was evenly divided into it.
Output the result of the function to the console.
Here's my code so far, I know I'm doing something very wrong and can't figure it out. I have it in two functions, can't figure out how to make it one, and my output doesn't look correct either.
function divisibles(number, myArrayLower) {
let divisibleArray = [];
let count = 0;
for (let i = 0; i < myArrayLower.length; i++) {
if (number % myArrayLower[i].value === 0) {
divisibleArray[count++] = {name: myArrayLower[i].name, value: myArrayLower[i].value};
}
}
return divisibleArray;
}
function findDivisibles(myArrayUpper, myArrayLower) {
let divisiblesArray = [];
for (let i = 0; i < myArrayUpper.length; i++) {
let divisibleArray = divisibles(myArrayUpper[i].value, myArrayLower);
divisiblesArray[i] = {
name: myArrayUpper[i].name, value: myArrayUpper[i].value,
found: divisibleArray
};
}
return divisiblesArray;
}
Here's the call function
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
Here is my console.log
let resultArray = findDivisibles(myArrayUpper, myArrayLower);
for (let i = 0; i < resultArray.length; i++) {
console.log("Name: " + resultArray[i].name + " Value: " + resultArray[i].value + " Found: ");
let tmpArray = resultArray[i].found;
for (let k = 0; k < tmpArray.length; k++) {
console.log(" Name: " + tmpArray[k].name + " Value: " + tmpArray[k].value);
}
}
The desired output will look something like this
{
name: ”Nathan15”,
value: 15,
found:[
{ name: “nathan3”, value: 3},
{ name: “nathan15”, value: 15} ]
}
This is my output
My output looks like this
Name: Nathan586 Value: 2930 Found:
Name: Nathan587 Value: 2935 Found:
Name: Nathan588 Value: 2940 Found:
Name: nathan1 Value: 3
Name: nathan2 Value: 6
Name: nathan4 Value: 12
I can add the rest of the question, code I wrote for previous parts of this question if it helps

How to group elements of array

I have an array:
var arr = ['User1','123456','User2','456789','User3','546544'];
How can I get array of object like this:
var arr2 = [{name: 'User1', id: 123456},{name: 'User2', id: 456789}, {name: 'User3', id: 546544}];
I tried this:
arr.forEach(function (item, i, arr) {
arr2.push(
{
name: arr[i],
id: arr[i + 2]
}
);
});
In a simple way, you need to do two things:
Check if the length is even.
Push it as how you require, by incrementing the loop twice.
var arr = ['User1', '123456', 'User2', '456789', 'User3', '546544'];
var arrObj = [];
if (arr.length % 2 === 0)
for (var i = 0; i < arr.length; i += 2)
arrObj.push({
"name": arr[i],
"id": parseInt(arr[i + 1], 10),
});
console.log(arrObj);
Look at the comments inside the code.
const arr = ['User1', '123456', 'User2', '456789', 'User3', '546544'];
// Ok, so what you to do is to group the infos and create a new object
// There is many function you can use, in the following example, I will use
// Array.reduce
// We gonna call couple, two values that goes together, like :
// User1 and 123456
// User2 and 456789
// ...
const ret = arr.reduce((tmp, x, xi) => {
// Add nothing for the first value of the couple
// We gonna ignore, User1, User2 and User3
if (xi % 2 === 0) return tmp;
return [
...tmp,
// Add a new value in the array
{
// The name is the first value of the couple
name: arr[xi - 1],
// The id is the second value of the couple
id: x,
},
];
}, []);
console.log(ret);
The for loop works on all versions of all computers and has the added advantage of being able to skip the index directly, something forEach can only do with a lot of extra code. Also forEach is slower than the for loop.
var arr1 = ['User1', '123456', 'User2', '456789', 'User3', '546544'], arr2 = [];
for (var i = 0; i < arr1.length - 1; i += 2) { // here is the i+=2
arr2.push({
"name": arr1[i],
"user": arr1[i + 1] // here is the i+1
});
}
console.log(arr2)
Or terser array
var arr1 = ['User1', '123456', 'User2', '456789', 'User3', '546544'], arr2 = [];
for (var i = 0; i < arr1.length - 1; i += 2) {
arr2.push({
[arr1[i]]: arr1[i + 1]
});
}
console.log(arr2)
A solution to your problem would be as follow :
var arr2 = [];
for (var i = 0; i < arr.length; i = i + 2) {
arr2.push({name : arr[i], id: arr[i + 1]})
}
Next time time try to show your trial code, you'll progress much more this way.

Sort two inter-related arrays (players and scores) and print results?

I would like to enter 3 players with 3 scores in using 2 arrays.
For now I stuck, concerning the ranking; how to do ???
Small example:
Player 1 : Jeremy
Score Jeremy : 12
Player 2 : Julien
Score Julien : 18
Player 3 : Olivia
Score Olivia : 22
For the ranking we should have
The first => Olivia with 22 scores
The second => Julien with 18 scores
The third => Jeremy with 12 scores
Here is my code.
function main() {
var players = new Array();
var scores = new Array();
for(i = 0; i<3; i++) {
players[i] = prompt("Player " + (i+1) + " : ");
scores[i] = prompt("Score " + (players[i]) + " : ");
}
}
Thank you advance.
Splitting data into two arrays is probably not the easiest way to go, but assuming you have no choice, I would use a custom sorting function and an additional array containing indices related to the other arrays :
main();
function main() {
var players = new Array();
var scores = new Array();
var ranking = new Array();
for (var i = 0; i < 3; i++) {
ranking[i] = i;
players[i] = prompt("Player " + (i + 1) + " : ");
scores[i] = prompt("Score " + (players[i]) + " : ");
}
indirectSort(3, ranking, scores);
for (var i = 0; i < 3; i++) {
var ithPlayer = players[ranking[i]];
var ithScore = scores[ranking[i]];
console.log(ithPlayer, ithScore);
}
}
function indirectSort (n, toBeSorted, toBeCompared) {
for (var i = 0; i < n - 1; i++) {
for (var j = i + 1; j < n; j++) {
var a = toBeCompared[toBeSorted[j]];
var b = toBeCompared[toBeSorted[i]];
if (a < b) {
var min = toBeSorted[j];
toBeSorted[j] = toBeSorted[i];
toBeSorted[i] = min;
}
}
}
}
Here is how the above code works :
players = ["John", "Jack", "Bob"];
scores = [2, 1, 3];
ranking = [0, 1, 2];
indirectSort(3, ranking, scores);
console.log(ranking);
// [1, 0, 2]
console.log(players[ranking[0]]);
// "Jack"
console.log(scores[ranking[0]]);
// 1
This will give you a sorted Players array, where each player has a name and a score
function main()
{
var players = new Array();
for(i = 0; i<3; i++){
let player = {};
player.name = prompt("Player " + (i+1) + " : ");
player.score = prompt("Score " + (players[i]) + " : ");
players[i] = player;
}
players.sort(function(a,b){
if (a.score < b.score)
return -1;
if (a.score> b.score)
return 1;
return 0;
})
console.log(players);
}
You could and should be storing each user as an object in an array like this:
function main(){
var players = [];
for(var i = 0;i<3;i++){
var player = {};
player.name = prompt("Enter user name");
var ranking = prompt("Enter user ranking");
player.ranking = parseInt(ranking);
players.push(player)
}
console.log("Players");
players.forEach(function(player){
console.log(player.name,player.ranking);
});
//Now sort based on ranking
players = players.sort(function(pA,pB){
return pA.ranking - pB.ranking;
});
players.forEach(function(player){
console.log(player.name,player.ranking);
});
}
main();
Try following. I am just using push of array(for adding an object to array). And for sorting you can use sort(for sorting array based on the score) of Array.Prototype. See below code.
var array=[];
function add(){
var x={};
x.name=prompt("Player " + (array.length+1) + " : ");
x.score=parseInt(prompt("Score " + (x.name) + " : "));
array.push(x);
array.sort((a,b)=>a.score<b.score)
console.log(array);
}
<button onclick="add()">add</button>
You should use array of objects instead of separate arrays like:
let data = [
{name: 'Jeremy', score: 12},
{name: 'Julien', score: 18},
{name: 'Olivia', score: 22}
];
You can then sort and print result with .sort():
let data = [
{name: 'Jeremy', score: 12},
{name: 'Julien', score: 18},
{name: 'Olivia', score: 22}
];
data.sort((a, b) => b.score - a.score);
console.log(`The first => ${data[0].name} with ${data[0].score} scores`);
console.log(`The second => ${data[1].name} with ${data[1].score} scores`);
console.log(`The third => ${data[2].name} with ${data[2].score} scores`);
However if for some reasons you want to stick with 2 arrays, you can also transform both arrays in single array of object and print result.
let players = ['Jeremy', 'Julien', 'Olivia'];
let score = [12, 18, 22];
function printResult(p, s) {
let a = p.reduce((a, c, i) => (a.push({name: c, score: s[i]}), a), [])
.sort((a, b) => b.score - a.score);
console.log(`The first => ${a[0].name} with ${a[0].score} scores`);
console.log(`The second => ${a[1].name} with ${a[1].score} scores`);
console.log(`The third => ${a[2].name} with ${a[2].score} scores`);
}
printResult(players, score);
Useful Resources:
Array.prototype.sort()
Template literals

How to fill an array with a for loop?

I’m having a lot of trouble learning how to use for loops to fill a new variable. As an example say if I have var year = [2010, 2000, 1992]; and var age = [];.
How would I use a for loop to fill in the age variable?
If this is a bad example, don’t use this. I just would like some help with understanding how to fill in empty arrays.
var names = ["Ace", "yoshi", "Lassie"];
var age = [25, 23, 5];
var u24 = [];
for (var i = 0; i < names.length; i++) {
if ([age] < 24) {
u24 += age[i]
console.log("hello " + names + " " + "you are" + age);
}
}
It is better to create objects that contain relevant data. Combining the name and age into a person object would help.
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var u24=[];
for (var i =0; i < persons.length; i++) {
var person = persons[i];
if(person.age < 24){
u24.push(person.age);
console.log("hello " + person.name + " " + "you are " + person.age);
}
}
console.log(u24);
But you can also use forEach like this:
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var u24=[];
persons.forEach(
function(person) {
if(person.age < 24){
u24.push(person.age);
console.log("hello " + person.name + " " + "you are " + person.age);
}
}
);
console.log(u24);
By making objects that include all relevant data your loops will never get out of sync. If you remove a person from the persons array then their name and age will go together.
UPDATE: Using a filter
var persons = [
{
name: "Ace",
age: 25
},
{
name: "yoshi",
age: 23
},
{
name: "Lassie",
age: 5
}
];
var youngPersons = persons.filter(
function(person) {
return (person.age < 24);
}
);
console.log(youngPersons);
Or using an ES6 Arrow Function
var persons = [
{ name: "Ace", age: 25 },
{ name: "yoshi", age: 23 },
{ name: "Lassie", age: 5 }
];
var youngPersons = persons.filter((person) => person.age < 24);
console.log(youngPersons);
This provides back an array of the persons that match your Age under 24 criteria.
If all you want to do is fill in the age array with a loop, you can try this:
let years = [2010, 2000, 1992],
age = [],
d = new Date().getFullYear();
years.forEach(year => age.push(d - year));
console.log(age);
As regards the relationship between age and names, I think Intervalia has explained that.
A working version.
Please compare it with your code to see the differences. Arrays always got me when I was starting out, and the syntax with different across languages, despite the reuse of bracket symbols.. AutoIt language still trips me up :P
var names = ["Ace", "yoshi", "Lassie"];
var age = [25, 23, 5];
//Use array.push() to append values
var u24 = [];
//variable i counts up to names.length
//because i++ means 'add one' to i
for (var i = 0; i < names.length; i++) {
//if ([age] < 24) {u24 += age[i];
//age at the count 'i' (which is
//counting)
//is achieved by array[at_index]
if (age[i] < 24) {
u24.push(age[i]); //add it to the end
console.log("Hello " + names[i] +
", you are " + age[i]);
}
}

Categories