javascript loop string comparison headache - javascript

console.log(previousCompetitors);
console.log(competitors);
if(data.isVisible) {
var moveIndexTo = [];
for(var q=0; q<competitors.length;q++) {
moveIndexTo.push(-1);
}
for(var i = 0; i<competitors.length; i++) {
for(var j = 0; j<previousCompetitors.length; j++) {
console.log(competitors[i].name);
console.log(previousCompetitors[j].name);
if(competitors[i].name === previousCompetitors[j].name) {
moveIndexTo[j]= i;
break;
}
}
}
console.log(moveIndexTo);
}
I'm slowly going insane trying to figure out what is happening here. I have an array of competitor data that updates in order. They are both arrays and I want to track the changes from the previous ordering.
I console.log the data and can see that the data order has been changed yet every single time the moveIndexTo array ends up being [0,1,2,3,4,5] implying that previousCompetitors an Competitors have equal order. How can they be changed between when I console.log them at the top of the code block to when I perform the string comparison?
Competitors and previousCompetitors take roughly the form
[{name:'name1'},{name:'name2'},{name:'name3'},{name:'name4'},{name:'name5'},{name:'name6'}]
with a lot more going on in each object. So If that was previousCompetitors then competitors would be something like
[{name:'name6'},{name:'name2'},{name:'name3'},{name:'name4'},{name:'name5'},{name:'name1'}].
Note the switch of name1 and name6. So I would expect moveIndexTo to be [5,1,2,3,4,0].

Just try this : moveIndexTo[i] = j;
fiddle at : https://jsfiddle.net/c9mbbpjj/

Related

Iterate over a Range fast in Excelscript for web

I want to check that a range of cell are empty or has any values in them, I use this for loop :
for (let i = 0; i <= namesRange.getCellCount(); i++) {
if (namesRange.getCell(i,0).getText() == "")
{
break;
}
bookedCount += 1;
}
However this iteration is extremely slow (as is the use of Range.getValue, but the console warns you that iterating with .getValue is slow, does not warn you with getText) It takes several seconds to iterate over a very short list of 10 elements.
Is there any way to check for the values of a cell in a speedy manner using ExcelScripts?
Does this mean that, even if I develop a UDF or a ribbon Add-In with office.js and Node.js it will also be this extremely slow for iterating over cells?
Is there any way to make this faster?
The reason your code is likely performing slowly is that the calls to getCell() and getText() are expensive. Instead of performing these calls every time in the loop you can try a different approach. One approach is to get an array of the cell values and iterate over that. You can use your namesRange variable to get the array of values. And you can also use it to get the row count and the column count for the range. Using this information, you should be able to write nested for loops to iterate over the array. Here's an example of how you might do that:
function main(workbook: ExcelScript.Workbook) {
let namesRange: ExcelScript.Range = workbook.getActiveWorksheet().getRange("A1");
let rowCount: number = namesRange.getRowCount();
let colCount: number = namesRange.getColumnCount();
let vals: string[][] = namesRange.getValues() as string[][];
for (let i = 0; i < rowCount; i++) {
for (let j = 0; j < colCount; j++) {
if (vals[i][j] == "") {
//additional code here
}
}
}
}
Another alternative to the first answer is to use the forEach approach for every cell in the range of values.
It can cut down the amount of variables you need to achieve the desired result.
function main(workbook: ExcelScript.Workbook)
{
let worksheet = workbook.getActiveWorksheet();
let usedRange = worksheet.getUsedRange().getValues();
usedRange.forEach(row => {
row.forEach(cellValue => {
console.log(cellValue);
});
});
}

JS multidimensional array spacefield

i wanna generate a 3x3 field. I want to do this with JS, it shall be a web application.
All fields shall inital with false. But it seems so that my code is not working correctly, but i don't find my fault. The goal is, that every spacesector is accessible.
Thats my idea:
// define size
var esize = generateSpace(3);
}
space[i] = false is replacing the array with a single boolean value false, not filling in all the entries in array you just created. You need another loop to initialize all the elements of the array.
function generateSpace(x) {
var space = [];
for (var i = 0; i < x; i++) {
space[i] = [];
for (var j = 0; j < x; j++) {
space[i][j] = false;
}
}
return space;
}
Also, your for() loop condition was wrong, as you weren't initializing the last element of space. It should have been i < space.length.
And when it's done, it needs to return the array that it created.
Since I got somewhat bored and felt like messing around, you can also initialize your dataset as shown below:
function generateSpace(x) {
return Array.apply(null, Array(x)).map(function() {
return Array.apply(null, Array(x)).map(function() {
return false;
});
});
}
The other functions work equally well, but here's a fairly simply looking one using ES6 that works for any square grid:
function generateSpace(x) {
return Array(x).fill(Array(x).fill(false));
}

How to create and display result one at a time in an infinite loop in javascript?

I'm fairly new to HTML and Javascript. I want to know how to create an infinite loop from, let's say, myArray, list, or whatever and then display result one at a time. Can you please give me an example, hints, or anything with detailed explanation of how it works? I just want to understand on how things work. Thanks!
A very basic loop is a while loop:
while (condition) {
//code block to be executed
}
Typically you would use it like so:
var i = 0;
while (i < 10) {
//code block to be executed
i++;
//This block of code will continue until i >= 10
//adding 1 to the value of I each iteration
}
Easiest way to do a endless loop:
while (true) {
code block to be executed
}
//true will always be true so this will continue until it
//hits a return; statement, the end of time, or the software
//or hardware gives up
A common mistake that end up in an endless loop:
var i = 0;
while (i < 10) {
code block to be executed
//In this example i is never being increased so
//i will always be less than 10
}
A very practical way to do a while loop correctly:
var array = ['a','b','c'];
var i = 0;
while (i < array.length) {
alert(array[i]);
i++;
}
//This will alert a, alert b, then alert c
Another way to do the above is using a for loop:
var array = ['a','b','c'];
for (var i = 0; i < array.length; i++) {
alert(array[i];
}
//for loops are a good practice because you are less
//likely to leave out steps like defining the iterator,
//or increasing the iterator
OP
I'm trying to create something using HTML/Javascript that everytime I press a button called next item (I created one using <form></form>) it would display an item, or an image. The trick is I don't know how to keep displaying the item after the last position. After the last position it should go back to the first position. For example, for the array that you provide in your example you have [a, b, c], after I displayed c and press the button again I want to display a again and so forth. Can you give me hints or any other valuable info on how to do this?
Answer
JSFiddle Example:
http://jsfiddle.net/d2809p6z/
HTML
<button id="button">click me</div>
JS
var array = ['a','b','c'];
var index = 0;
document.getElementById('button').onclick=function(){
if (index >= array.length) {
index = 0;
}
alert(array[index]);
index++;
};

Can I select 2nd element of a 2 dimensional array by value of the first element in Javascript?

I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?

Merge loops with jQuery.extend: last value is always the same?

I have two arrays of "hashes". I need to merge them together so the end result is another array of hashes, except the number of entries is the product of the two arrays.
inhabitants = {}
idx = 0
for (i=0; i<persons.length; i++) {
person = persons[i];
for (j=0; j<houses.length; j++) {
house = houses[j];
console.log(house);
inhabitants[idx] = $.extend(person,house);
console.log(inhabitants[idx]);
idx++;
}
}
What I end up with is a silly number of entries that depends on the ordering of the parameters in the $.extend() line. And the "house" entry that is added is ALWAYS THE LAST ENTRY IN THE ARRAY.
Clearly this $.extend() from jQuery is not doing what I expect. Can anyone help?
$.extend(a, b) merges b into a, and returns a.
The return value you're using but it seems you were missing the fact that a is also being changed - you're currently assigning the same variable person to inhabitants[idx] each time.
I'm not really getting what you are trying to do, but anyway just a few hints. It's a good idea to place all the semicolons (here they're missing in the first and second line). Then I don't see why you are using an object instead of an array where you just have to push new items. Another thing is that in js it is faster to cache the lengths of the persons and houses collections. I will try to come up with code how I understood your task, maybe I'm getting it wrong:
var inhabitants = [],
idx = 0,
personCount = persons.length,
houseCount = houses.length,
person = {},
house = {},
i = 0,
j = 0;
for (i = 0; i < personCount; i++) {
person = persons[i];
for (j = 0; j < houseCount; j++) {
house = houses[j];
inhabitants.push($.extend({}, person, house);
}
}
So to me it seems like a database join between the two tables persons and houses. Is this what you meant?

Categories