How can speed up search loop? - javascript

There is a cycle with the condition how can it be optimized so that the search is faster?
for (var i = 0; i < db.rows.length; i++) {
for (var j = 0; j < user.rows.length; j++) {
for (var k = 0; k < work.length; k++) {
if (db.rows[i].LOGIN === user.rows[j].login && work[k].name === db.rows[i].NAME) {
}
}
}
}

This is typically something that you would expect to see executed on the database.
That being said, you can split up the condition, so that you don't need to perform the second nested loop for every row:
for (var i = 0; i < db.rows.length; i++) {
for (var j = 0; j < user.rows.length; j++) {
if (db.rows[i].LOGIN === user.rows[j].login) {
for (var k = 0; k < work.length; k++) {
if (work[k].name === db.rows[i].NAME) {
}
}
}
}
}

You could take two Maps for the user logins and work names.
var userLogins = new Map(user.rows.map(o => [o.login, o])),
workNames = new Map(o => [o.name, o]),
for (var i = 0; i < db.rows.length; i++) {
if (userLogins.has(db.rows[i].LOGIN) && workNames.has(work[k].name)) {
// do something
}
}
If you need just the simple check with using the objects of user.rows or work, you could take a Set instead.
var userLogins = new Set(user.rows.map(({ login } => login)),
workNames = new Set(({ name }) => name),
for (var i = 0; i < db.rows.length; i++) {
if (userLogins.has(db.rows[i].LOGIN) && workNames.has(work[k].name)) {
// do something
}
}

Related

Javascript array contents are defined as empty

i used a console.log for a 3d array and this is its contents
for the second its contents are clear
for(let mmm = 0; mmm < NumOfPatterns;mmm++)
{
for(let i = 0; i < 36; i++)
{
for(let j = 0; j < 36; j++)
{
patterns[mmm][i][j] = 0;
console.log(patterns[mmm][i][j]);
}
}
}
I use this function just to define every value to 0
I think you should check if the arrays exist:
const NumOfPatterns = 10
const DEFAULT_ARR_LENGTH = 36
let arr3d = []
// checking if the referenced elements exist
// if not, create them on the first iteration
for (let mmm = 0; mmm < NumOfPatterns; mmm++) {
if (typeof arr3d[mmm] === "undefined") arr3d[mmm] = []
for (let i = 0; i < DEFAULT_ARR_LENGTH; i++) {
if (typeof arr3d[mmm][i] === "undefined") arr3d[mmm][i] = []
for (let j = 0; j < DEFAULT_ARR_LENGTH; j++) {
arr3d[mmm][i].push(0)
}
}
}
console.log(arr3d)

JavaScript nested for loop resulting in displaying only last iterating object value

I have a json array object which is getting constructed using two different array objects.
But after looping I'm getting the value of the last looped value for every array.
But for the serial number element I'm getting the value of the last iterated value. Am I missing something?
for (z = 0; z < postAdvancedAddressCheckRequest.addressCheck.energyQuoteAddress.electricityMeter.length; z++) {
for (i = 0; i < ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches.length; i++) {
for (j = 0; j < ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches[i].Meters.length; j++) {
for (k = 0; k < ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches[i].Meters[j].MeterDetails.length; k++) {
if (ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches[i].Meters[j].MeterDetails[k].Key === "meter_serial_number") {
var serialNumber1 = ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches[i].Meters[j].MeterDetails[k].Value;
}
}
electricityMeterObject = {
"Check": true,
"serialNumber": serialNumber1
}
electricityArray.push(electricityMeterObject);
}
}
}
This is easier to debug
const meter = postAdvancedAddressCheckRequest.addressCheck.energyQuoteAddress.electricityMeter,
matches = ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches;
for (let z = 0; z < meter.length; z++) {
for (let i = 0; i < matches.length; i++) {
for (let j = 0; j < matches.Meters.length; j++) {
for (let k = 0; k < matches[i].Meters[j].MeterDetails.length; k++) {
if (matches[i].Meters[j].MeterDetails[k].Key === "meter_serial_number") {
electricityArray.push({
"Check": true,
"serialNumber": matches[i].Meters[j].MeterDetails[k].Value
});
}
}
}
}
}
Or
const meter = postAdvancedAddressCheckRequest.addressCheck.energyQuoteAddress.electricityMeter,
matches = ecoesGetTechnicalDetailsByMpanResponse.Results[0].UtilityMatches;
meters.forEach(meter => {
matches.forEach(match => {
match.Meters.forEach(meter => {
meter.MeterDetails.forEach(detail => {
if(detail.Key === "meter_serial_number") {
electricityArray.push({
"Check": true,
"serialNumber": matches[i].Meters[j].MeterDetails[k].Value
});
}
})
})
})
})

How do I return a variable from nested For Loops in JavaScript without using a global variable?

Here is my code sans input
// Check if three addends equal sum and return the product if so
let result;
function addNumbers(first,second,third,sum) {
if (first + second + third === sum) {
result = first * second * third;
return (first * second * third);
}
};
// find three numbers in list that add up to specific number
function testResult(list,sum) {
let firstAddend;
let secondAddend;
let thirdAddend;
for (let i = 0; i < list.length; i++) {
firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
thirdAddend = list[k];
addNumbers(firstAddend,secondAddend,thirdAddend,sum);
}
}
}
};
What I want is testResult() to return the result from addNumbers() when it returns the product. I want to get rid of let result; and result = ... in addNumbers(). I've been confused about scope but I think I'm starting to understand. Does each for loop contain the scope of the previous? If anyone is interested this is from Advent of Code Day 1. I am not certain if having the data is necessary here. If it is let me know and I will edit accordingly.
Does each for loop contain the scope of the previous?
Yes, it does. Whenever you create a sub-scope, all the variables in the previous scope are available. So, you don't actually have to declare firstAddend and secondAddend and thirdAddend ahead of time:
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
addNumbers(firstAddend,secondAddend,thirdAddend,sum);
}
}
}
}
Next, the return means that when you call the function, it takes on the value that you return. So, you don't need a global result variable, as you can just utilize the return value. However, you should move the if statement out of the addNumbers function and into the testResult function, as you need to know when to return, not just what to return. In fact, the addNumbers function is simply enough to where it should just go directly into testResult:
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
if (firstAddend + secondAddend + thirdAddend === sum) {
return firstAddend * secondAddend * thirdAddend;
}
}
}
}
}
For practice, if you want the function, you could do something like the following:
function addNumbers(first,second,third,sum) {
if (first + second + third === sum) {
return (first * second * third);
} else {
return null; // return some value so the calling function knows that no sum was found
}
}
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
let result = addNumbers(firstAddend, secondAddend, thirdAddend, sum);
if (result !== null) {
return result;
}
}
}
}
}

Search words in array based on few words

Hi I have a problem how to search for words containing at least part of a word. What I mean words that have word I find in array javascript without built-in function except only PUSH.
This task requires no index.of, slice, substr, substring, regex etc. Only PUSH
This my code so far:
function wordsChecker(sentences, search) {
var result = []
for (var i = 0; i < sentences.length; i++) {
var isCheck = false
for (var j = 0; j < sentences.length; j++) {
for (var k = 0; k < search.length; k++) {
if (sentences[i][j] == search[k]) {
isCheck = true
}
}
}
if (isCheck == true) {
result.push(sentences[i])
}
}
return result
}
console.log(wordsChecker(['broom, room, rox, show room, stroom, root, rote, brother'], 'roo'))
//expected output : [broom, room, show room, stroom, root]
Thanks in advance
At the first you should make correct array. I hope this code work for you
function wordsChecker(sentences, search) {
var result = [], k = 0;
for (var i = 0; i < sentences.length; i++) {
var isCheck = false;
for (var j = 0; j < sentences[i].length; j++) {
while (k < search.length) {
if (sentences[i][j] == search[k]) {
isCheck = true;
k++;
break;
}
else {
isCheck = false;
k = 0;
break;
}
}
}
if (isCheck === true && k === search.length) {
result.push(sentences[i]);
k = 0;
}
}
return result;
}
console.log(wordsChecker(['broom', 'room', 'rox', 'show room', 'stroom', 'root', 'rote', 'brother'], 'roo'));

remove value from two tables

I have two table is I remove the value in both tables if in a table of the value is marked by a flag to false
this.notInModel = function (tab1, tab2) {
for (var i = 0; i <= tab1.length - 1; i++) {
if (!tab1[i].inModel) {
for (var j = 0; j <= tab2.length - 1; j++) {
if(tab1[i].name === tab2[j].name)
tab2.splice(j, 1);
}
}
}
for (var i = 0; i <= tab2.length - 1; i++) {
if (!tab2[i].inModel) {
for (var j = 0; j <= tab1.length - 1; j++) {
if(tab2[i].name === tab1[j].name)
tab1.splice(j, 1);
}
}
}
}
I think my curls are a bit repetitive and wanted to know if we could not refactor the code ..?
thank you.
Try this:
this.notInModel = function (tab1, tab2) {
for (var i = tab1.length; i--; ) {
for (var j = tab2.length; j--; ) {
if(tab1[i].name !== tab2[j].name)
continue;
var tab2InModel = tab2[j].inModel;
if(!tab1[i].inModel)
tab2.splice(j, 1);
if(!tab2InModel)
tab1.splice(i, 1);
}
}
}
The trick is to loop through both tabs in reverse order and make the checks for the name and inModel properties for every element combination.
DEMO
You could make it more modular by creating a new function to iterate through the arrays like this:
this.notInModel = function (tab1, tab2) {
function nim(t1,t2) {
for (var i = 1; i <= t1.length - 1; i++) {
if (!t1[i].inModel) {
for (var j = 1; j <= t2.length - 1; j++) {
if(t1[i].name === t2[j].name)
t2.splice(j, 1);
}
}
}
}
nim(tab1,tab2);
nim(tab2,tab1);
}
The following code seems to be equivalent, though I could not test without the definition of splice or without knowing how inModel field is set.
this.notInModel = function (tab1, tab2) {
for (var i = 1; i <= tab1.length - 1; i++) {
for (var j = 1; j <= tab2.length - 1; j++) {
if(!tab1[i].inModel) {
if (tab1[i].name === tab2[j].name)
tab2.splice(j, 1);
}
if(!tab2[j].inModel) {
if (tab1[i].name === tab2[j].name)
tab1.splice(i, 1);
}
}
}
}

Categories

Resources