Removing one item from multiple identical arrays - javascript

I am trying to remove items from arrays that are all the same. Interestingly, it works when my arrays are different. The following code works as intended, removing the Fireman from team1, the Pyromancer from team2, the Aronist from team3, and the Vigilante from team4.
var options = {};
options.characters = ["Fireman","Missionary","Vigilante","Corrupt Policeman","Suicide Bomber","Arsonist","Gunman","Pyromancer","Hypnotist","Picklock","Policeman","Child","Prostitute"];
this._team1Characters = options.characters.concat(["test1"]);
this._team2Characters = options.characters.concat(["test2"]);
this._team3Characters = options.characters.concat(["test3"]);
this._team4Characters = options.characters.concat(["test4"]);
var submissions = {};
submissions.character1 = "Fireman";
submissions.character2 = "Pyromancer";
submissions.character3 = "Arsonist";
submissions.character4 = "Vigilante";
var i = 5;
while(--i){
if(submissions["character"+i]){
this["_team"+i+"Characters"].splice( this["_team"+i+"Characters"].indexOf(submissions["character"+i]), 1 );
}
}
alert(this._team1Characters);
alert(this._team2Characters);
alert(this._team3Characters);
alert(this._team4Characters);
However, if the four arrays are the same, all arrays end up the same (all lack the Fireman, the Pyromancer, the Aronist and the Vigilante). This is the code causing the problem:
var options = {};
options.characters = ["Fireman","Missionary","Vigilante","Corrupt Policeman","Suicide Bomber","Arsonist","Gunman","Pyromancer","Hypnotist","Picklock","Policeman","Child","Prostitute"];
this._team1Characters = options.characters;
this._team2Characters = options.characters;
this._team3Characters = options.characters;
this._team4Characters = options.characters;
var submissions = {};
submissions.character1 = "Fireman";
submissions.character2 = "Pyromancer";
submissions.character3 = "Arsonist";
submissions.character4 = "Vigilante";
var i = 5;
while(--i){
if(submissions["character"+i]){
this["_team"+i+"Characters"].splice( this["_team"+i+"Characters"].indexOf(submissions["character"+i]), 1 );
}
}
alert(this._team1Characters);
alert(this._team2Characters);
alert(this._team3Characters);
alert(this._team4Characters);
What's the reason for this?

When you do this._team1Characters = options.characters; you're passing a reference, so you really end up with lots of references to the same array. Consequently, when you change that single array, you'll see the change through any of the references.
If you want to copy an array, use Array.prototype.slice().
this._team1Characters = options.characters.slice();
...

since you are assigning the reference of the same variable to all, so all the removals are essentially happening from same array options.characters
try doing it this way
this._team1Characters = options.characters.concat( [] );
this._team2Characters = options.characters.concat( [] );
this._team3Characters = options.characters.concat( [] );
this._team4Characters = options.characters.concat( [] );
this will ensure that all get the same values in a different array and values in other arrays are not affected when removed from one array

Related

Javascript - Adding new element to array using for loop

I'm trying to convert url. Using for loop to extract Acura, Audi. Here what I got so far:
var newSrpParams = 'year=2020-2022&make=Acura&make=Audi&model=A3&model=A5&trim=2.0T%20Premium&trim=2.0T%20S%20line%20Premium&normalBodyStyle=Hatchback&normalBodyStyle=Sedan&odometer=13000-38000&internetPrice=20000-50000';
const newSrpParamsArray = newSrpParams.split("&");
var oldSrpParams;
var makes = [];
for(var i = 0 ; i < newSrpParamsArray.length; i++){
if(newSrpParamsArray[i].includes('make')) {
const make = newSrpParamsArray[i].replace('make=','')
makes.push(make);
console.log(makes)
}
};
The result is
[ 'Acura' ]
[ 'Acura', 'Audi' ]
As you see it has one more array. Is there a way to get only [ 'Acura', 'Audi' ]?
FYI there's a native solution for getting values a from query string, check URLSearchParams
var newSrpParams = 'year=2020-2022&make=Acura&make=Audi&model=A3&model=A5&trim=2.0T%20Premium&trim=2.0T%20S%20line%20Premium&normalBodyStyle=Hatchback&normalBodyStyle=Sedan&odometer=13000-38000&internetPrice=20000-50000';
const makes = new URLSearchParams(newSrpParams).getAll('make');
console.log(makes);
That is happening because you are logging the array inside the for loop. If you move it outside you will get
['Acura', 'Audi']
The Code:
var newSrpParams = 'year=2020-2022&make=Acura&make=Audi&model=A3&model=A5&trim=2.0T%20Premium&trim=2.0T%20S%20line%20Premium&normalBodyStyle=Hatchback&normalBodyStyle=Sedan&odometer=13000-38000&internetPrice=20000-50000';
const newSrpParamsArray = newSrpParams.split("&");
console.log(newSrpParamsArray)
var oldSrpParams;
var makes = [];
for(var i = 0 ; i < newSrpParamsArray.length; i++){
if(newSrpParamsArray[i].includes('make')) {
const make = newSrpParamsArray[i].replace('make=','')
console.log(make)
makes.push(make);
}
};
console.log(makes) // The change
You were consoling the results inside the if statement it will run two times. So as a result make[] array print two times. That's why you get the two arrays.
var newSrpParams = 'year=2020-2022&make=Acura&make=Audi&model=A3&model=A5&trim=2.0T%20Premium&trim=2.0T%20S%20line%20Premium&normalBodyStyle=Hatchback&normalBodyStyle=Sedan&odometer=13000-38000&internetPrice=20000-50000';
const newSrpParamsArray = newSrpParams.split("&");
var oldSrpParams;
var makes = [];
for(var i = 0 ; i < newSrpParamsArray.length; i++){
if(newSrpParamsArray[i].includes('make')) {
const make = newSrpParamsArray[i].replace('make=','')
makes.push(make);
}
};
console.log(makes)
Make sure to console make[] from outside of the for a loop. That's only. I couldn't see any other wrong line in your code.
Why not use URLSearchParams?
and you can replace the URL with window.location.href
let url = new URL(`http://localhost?year=2020-2022&make=Acura&make=Audi&model=A3&model=A5&trim=2.0T%20Premium&trim=2.0T%20S%20line%20Premium&normalBodyStyle=Hatchback&normalBodyStyle=Sedan&odometer=13000-38000&internetPrice=20000-50000`)
let params = new URLSearchParams(url.search).getAll("make")
console.log(params)

Trying to create a matrix with random numbers in JavaScript produces a matrix where all the rows are the same

When I try to create a matrix with random numbers, the matrix rows all appear the same. How do I fix this? The code for the problem is:
var sudokuRowMatrix = [];
var numbers = [];
var randomizedArray = [];
var sudokuColumnArray = [];
for(i=0;i<=8;i++){
numbers[i]=i+1;
sudokuRowMatrix[i] = [];
sudokuColumnArray[i] = [];
}
function RandomizeArray(array){
for(arrayIndex=0;arrayIndex<=8;arrayIndex++){
randomArrayIndex = Math.floor(Math.random()*9);
randomArrayIndex2 = Math.floor(Math.random()*9);
placeHolder = array[randomArrayIndex];
array[randomArrayIndex]=array[randomArrayIndex2];
array[randomArrayIndex2] = placeHolder;
}
return array;
}
for(rowNumber=0;rowNumber<=8;rowNumber++){
sudokuRowMatrix[rowNumber] = RandomizeArray(numbers);
}
When you call RandomizeArray(numbers) you pass the numbers array as a reference.
This means, that you always shuffle the same array and set it as a row in your Sudoku matrix and therefore shuffle all of your rows since they all hold the same reference.
An easy way to fix this, is to destructure your array before passing it to your method:
sudokuRowMatrix[rowNumber] = RandomzieArray([...numbers]);
You can find my source here.

cannot iterate through array and change value in JS

I have to iterate through an array, change one of its values, and create another array refelecting the changes.
this is what I have so far:
JS:
var arr = new Array();
arr['t1'] = "sdfsdf";
arr['t2'] = "sdfsdf";
arr['t3'] = "sdfsdf";
arr['t4'] = "sdfsdf";
arr['t5'] = "sdfsdf";
var last = new Array();
for (var i = 0; i <= 5; i++) {
arr['t2'] = i;
last.push(arr);
}
console.log(last);
Unfortunately, these are my results
As you can see, I am not getting the results needed as 0,1,2.. instead I am getting 2, 2, 2..
This is what i would like my results to be:
How can I fix this?
You have to make a copy, otherwise you are dealing with reference to the same object all the time. As it was said before - javascript does not have associate arrays, only objects with properties.
var arr = {}; // empty object
arr['t1'] = "sdfsdf";
arr['t2'] = "sdfsdf";
arr['t3'] = "sdfsdf";
arr['t4'] = "sdfsdf";
arr['t5'] = "sdfsdf";
var last = new Array();
for (var i = 0; i <= 5; i++) {
var copy = JSON.parse(JSON.stringify(arr)); //create a copy, one of the ways
copy['t2'] = i; // set value of its element
last.push(copy); // push copy into last
}
console.log(last);
ps: you can use dot notation arr.t1 instead of arr['t1']
The array access with ['t2'] is not the problem. This is a regular JavaScript feature.
The problem is: You are adding the SAME array to "last" (5 times in code, 3 times in the screenshot).
Every time you set ['t2'] = i, you will change the values in "last" also, because they are actually just references to the same array-instance.
You must create a copy/clone of the array before you add it to "last".
This is what will happen in all languages where arrays are references to objects (Java, C#...). It would work with C++ STL though.

How do I overwrite object properties in an array?

I would like to overwrite a certain allOrders[i] with data, similar to how I create a new one. For some reason I can't figure out what to search on.
I have an array of objects allOrders.
I have an object BusinessCard. I take the form fields, serialize() them, clean up the data with a regex, then push the them into an array.
allOrders.push(new BusinessCard(currentOrder.quantity, currentOrder.FullName, currentOrder.Title, currentOrder.CellNumber, currentOrder.OfficeNumber, currentOrder.FaxNumber, currentOrder.EmailAddress, currentOrder.Address, currentOrder.website, currentOrder.price));
I've tried searching for overwriting existing object properties in an array and the likes and haven't figured out what to do here.
My best guess was allOrders[i].push -- but it seems to me that I have to write a new function to replace each property in the object.
Right now I am using(because using serialize() on the form inputs doesn't help me at all:
allOrders[i].quantity = $('#bcQuantity').val();
allOrders[i].fullname = $('#fullName').val();
allOrders[i].title = $('#Title').val();
allOrders[i].cell = $('#CellNumber').val();
allOrders[i].office = $('#OfficeNumber').val();
allOrders[i].fax = $('#FaxNumber').val();
allOrders[i].email = $('#EmailAddress').val();
allOrders[i].address = $('#Address').val();
allOrders[i].website = $('#website').val();
allOrders[i].price = $('#bcCostBeforeCart').text();
There has to be a smarter way to do this. Thank you.
EDIT:
function getFormData(formId) {
var currentForm = '#' + formId;
var currentPrice = $('#bcCostBeforeCart').text();
var currentFormData = $(currentForm).serialize();
var currentFormDataFinal = currentFormData + '&price=' + currentPrice;
return JSON.parse('{"' + decodeURI(currentFormDataFinal.replace(/\+/g, " ").replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}');
}
MEANING i could be using
currentOrder = getFormData('businessCardForm');
then
allOrders[i] = currentOrder;
Seems odd that you would be updating all items with the selector's you're using, but I would wrap up getting the updated order information then, you can run thru a loop.
Depending on your output, as long as it's outputing the respective properties and values of an order object you could just do:
for(int i =0; i < allOrders.length; i++){
var currentFormId = '' // update this for each iteration.
allOrders[i] = getFormData(currentFormId);
}
allOrders[i] = getUpdatedOrder();
function getUpdatedOrder() {
var order = {};
order.quantity = $('#bcQuantity').val();
order.fullname = $('#fullName').val();
order.title = $('#Title').val();
order.cell = $('#CellNumber').val();
order.office = $('#OfficeNumber').val();
order.fax = $('#FaxNumber').val();
order.email = $('#EmailAddress').val();
order.address = $('#Address').val();
order.website = $('#website').val();
order.price = $('#bcCostBeforeCart').text();
return order;
}

javascript how to find number of children in an object

is there a way to find the number of children in a javascript object other than running a loop and using a counter? I can leverage jquery if it will help. I am doing this:
var childScenesObj = [];
var childScenesLen = scenes[sceneID].length; //need to find number of children of scenes[sceneID]. This obviously does not work, as it an object, not an array.
for (childIndex in scenes[sceneID].children) {
childSceneObj = new Object();
childSceneID = scenes[sceneID].children[childIndex];
childSceneNode = scenes[childSceneID];
childSceneObj.name = childSceneNode.name;
childSceneObj.id = childSceneID;
childScenesObj .push(childSceneObj);
}
The following works in ECMAScript5 (Javascript 1.85)
var x = {"1":1, "A":2};
Object.keys(x).length; //outputs 2
If that object is actually an Array, .length will always get you the number of indexes. If you're referring to an object and you want to get the number of attributes/keys in the object, there's no way I know to that other than a counter:
var myArr = [];
alert(myArr.length);// 0
myArr.push('hi');
alert(myArr.length);// 1
var myObj = {};
myObj["color1"] = "red";
myObj["color2"] = "blue";
// only way I know of to get "myObj.length"
var myObjLen = 0;
for(var key in myObj)
myObjLen++;

Categories