remove value from two tables - javascript

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);
}
}
}
}

Related

using splice inside 2D Array in Javascript

I've created this 2D array, and I'm trying to delete the rows that are having 5 "ones" or more,
I tried it with splice (a.splice(j,1)) but it doesn't work . I think because when using this method it changes the whole quantity of rows and that's affects the for loops.
Is it because I don't use splice correctly or should I use different method ?
Thanks !
a = Array(7).fill(0).map(x => Array(10).fill(0))
for (let i = 0; i < 5; i++) {
a[1][i + 2] = 1;
a[4][i + 2] = 1;
a[5][i + 2] = 1;
}
console.log(a);
let count = 0;
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 10; i++) {
if (a[j][i] == 1) {
count = count + 1;
}
}
if (count > 4) {
console.log("Line" + j);
// a.splice(j,1);
}
count = 0;
// a.splice(j,1);
}
Your splice is correct but you move forward through the array (j is incremented). To do this type of operation you need to move backward through the array (j is decremented) - this way the changing array indices don't intefere with your loop.
See the example below:
a = Array(7).fill(0).map(x => Array(10).fill(0))
for (let i=0; i<5; i++) {
a[1][i+2] = 1;
a[4][i+2] = 1;
a[5][i+2] = 1;
}
console.log("Original array");
console.log(a);
for (let j = a.length - 1; j > 0; j--) {
var count;
for (let i = 0; i < a[j].length; i++) {
if (a[j][i] === 1) {
count += 1
}
}
if (count > 4) {
a.splice(j, 1);
}
count = 0;
}
console.log("Filtered array");
console.log(a);

How can speed up search loop?

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
}
}

Combine 10 cycles into one in Javascript

Here's my code with cycles and I want to make it shorter (in one cycle if possible).
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
}
for (i = 0; i < 9; i++) {
piece.addStep('down');
}
for (i = 0; i < 8; i++) {
piece.addStep('left');
}
for (i = 0; i < 7; i++) {
piece.addStep('up');
}
}
etc... to i < 1
I thought about it that case,
function plan(piece) {
for (i=10; i>1; i--){
piece.addStep('right');
piece.addStep('down');
piece.addStep('left');
piece.addStep('up');
}
but it's was wrong. Help pls!
here's look of task(maze)
You can add function for the repeating logic :
function addSteps(piece, n) {
while (n--) {
piece.addStep(piece);
}
}
addSteps('right', 10);
addSteps('down', 9);
addSteps('left', 8);
addSteps('up', 7);
Simply combine all of them by introducing some if Checks.
For Example :
function plan(piece) {
for (i = 0; i < 10; i++) {
piece.addStep('right');
if(i < 9)
piece.addStep('down');
if(i < 8)
piece.addStep('left');
if(i < 7)
piece.addStep('up');
}
}
One option is:
function plan(piece) {
['right', 'down', 'left', 'up'].forEach((dir, ind) => {
for (let i = 0; i < 10 - ind; i++) {
piece.addStep(dir);
}
});
}
Doubt it is efficient, but you can be Array fill, concat, and forEach
var steps = [].concat(Array(10).fill("right"), Array(9).fill("down"), Array(8).fill("left"), Array(7).fill("up"))
steps.forEach(dir => piece.addStep(dir));
You could take nested loops and increment the index for getting the right direction.
var sequence = ['right', 'down', 'left', 'up'],
i, j,
k = 0,
l = sequence.length;
for (i = 0; i < 10; i++) {
for (j = i; j < 10; j++) {
document.getElementById('out').innerHTML += sequence[k] + '\n';
// or piece.addStep(sequence[k]);
}
++k;
k %= l;
}
<pre id="out"></pre>

Else statement won't work in for loop

I have a function here that is not working as I hoped it would. After a bit of testing, I discovered that it is not running the "else if" statement.
Here is the code:
getWeights : function() {
weights = [];
for (var i = 0; i < hiddenLayer.length; i++) {
weights[i] = {};
for (var j = 0; j < Object.keys(hiddenLayer[i]).length * 3; j++) {
if (i == 0) {
for (var t = 0; t < input.length; t++) {
weights[i]["weightsSet" + j] = 1;
}
}
else {
weightCalc = Object.keys(hiddenLayer[i - 1]).length;
for (var u = 0; u < Object.keys(hiddenLayer[i]).length * weightCalc; u++) {
weights[i]["weightsSet" + j] = 1;
}
}
}
}
},
Please help me find out why it won't work.
Any help is greatly appreciated.
EDIT
Removed comment
EDIT 2
I figured out the problem. Thanks for all the help :)
Try simplifying the function as follows and then debug to see what is happening:
getWeights : function() {
weights = [];
for (var i = 0; i < hiddenLayer.length; i++) {
weights[i] = {};
var limit = input.length;
if (i > 0) {
var weightCalc = Object.keys(hiddenLayer[i - 1]).length;
limit = Object.keys(hiddenLayer[i]).length * weightCalc;
}
for (var j = 0; j < Object.keys(hiddenLayer[i]).length * 3; j++) {
for (var t = 0; t < limit; t++) {
weights[i]["weightsSet" + j] = 1;
}
}
}
}
For any further help you would need to add data related to this code, and expected output in your question.
Check 2nd or 3rd for loop may be its running for infinitive number of times

"undefined is not an object" when create multidivisional array

I wrote the code:
var from = 6;
var io_arr = [0, 1, 2, 3];
var mem_arr = [0, 1, 2, 3];
var cpu_arr = [0, 1, 2, 3];
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
}
for (var i = 1; i <= io_arr.length; i++) {
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
Had the error
TypeError: undefined is not an object (evaluating 'x[i][j] = io_arr[i]')
What's wrong with this? I'm very new to JS, so sorry if the answer is obvious.
My guess:
for (var i = 1; i <= io_arr.length; i++) needs to be: for (var i = 0; i < io_arr.length; i++)
Or is there a specific reason why you modified this in the second for loop?
for (var i = 1; i <= io_arr.length; i++) {
is wrong, the first index is 0 not 1. An you are going too far, as the last index is not the value of io_arr.length but one smaller then the length (because it's starting at 0 ;) )
This should then work:
for (var i = 0; i < io_arr.length; i++) {
I checked the Code by changing this line, and it does not throw any error. This is just some programming basics you will have to get used to
So my original suggestion (in the comments) was to perform both operations in the same loop. That would allow you to get rid of two lines of code. So
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
}
for (var i = 1; i <= io_arr.length; i++) {
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
would be replaced be
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
for (var j = 0; j <= 3; j++) {
if(j == 0) {
x[i][j] = from + i - 1;
}
if (j == 1) {
x[i][j] = io_arr[i];
}
if (j == 2) {
x[i][j] = mem_arr[i];
}
if (j == 3) {
x[i][j] = cpu_arr[i];
}
}
}
The problem is that you want the first row of x to be empty. You can do that in a single loop by adding an if statement inside the loop:
var x = new Array(io_arr.length);
for (var i = 0; i < io_arr.length; i++) {
x[i] = new Array(4);
if (x === 0) continue;
for (var j = 0; j <= 3; j++) {
if(j === 0) {
x[i][j] = from + i - 1;
}
if (j === 1) {
x[i][j] = io_arr[i];
}
if (j === 2) {
x[i][j] = mem_arr[i];
}
if (j === 3) {
x[i][j] = cpu_arr[i];
}
}
}
This should give you your desired answer.
Note that I've changed == to ===, which should always be the preferred choice, because == performs weird conversions, and Javascript purists don't like it.

Categories

Resources