Building a 2D Array in Javascript - javascript

I've been trying to build a 2D array in javascript, but not having much success. I'm pulling some data from a DB and I then want to combine some fields into a 2D array in order to use it elsewhere in the code. Ideally what I want to end up with is:
mapLocs = [
['name a','location a',1],
['name b','location b',2],
['name c','location c',3]
]
here is the code I am using to build the mapLocs array:
for(i = 0;i < phtLen;i++){
var x = i + 1;
var myLocs = new Array(myPhotogs[i].phtName,myPhotogs[i].phtLoc,x);
console.log(myLocs);
mapLocs[i] = new Array(myLocs);
}
}
which is pretty much the method that I've gathered from reading similar problems here. The console.log() outputs an array consisting of the three elements I want, but if I try to access mapLocs it doesn't seem to consist of three arrays as I would have expected, but of three elements each of which is made up of the three elements in the myLoc array if that makes sense? So:
console.log(mapLocs[0][0]); // Joe Bloggs, SW1A 1AA, 1
where I was expecting just 'Joe Bloggs' and
console.logs(mapLocs[0][1]); // undefined
What am I doing wrong?

The explicit new Array() constructor does not take an array and make a new array identical to the argument array, but takes a list of arguments that you wish to be contained within the new array. So in the line
mapLocs[i] = new Array(myLocs)
mapLocs[i] is actually being set to
[[Joe Bloggs, SW1A 1AA, 1]]
Instead, you could say
mapLocs[i] = myLocs.slice()
which will clone myLocs and place it at index i in mapLocs, resulting in the output you want.

Related

Get a key from an array inside an array in javascript

var Game1 = ["name", "image", "genre"]
var Game2 = ["name2", "image2", "genre2"]
var Game3 = ["name3", "image3", "genre3"]
var games = [Game1, Game2, Game3]
I want to store some arrays inside an other array, as shown above, and I want to be able to show all of the names of the arrays. So here, I would like to get Game1[0], Game2[0] and Game3[0], but I want to get them from the games array.
How would I go about doing this?
I was thinking of using a for loop over games, but I'm not sure how to get the 0th element from the arrays inside the games array.
I'm quite new to javascript, which is why I could not figure this out.
You can access like below.
games[0][0] - will gives you the Game1[0] value
games[1][0] - will gives you the Game2[0] value
games[2][0] - will gives you the Game3[0] value
DEMO

Checking for existing array in array before pushing

I missing something when trying to push to an array while preventing duplicates.
I keep figuring out code that will push every occurence of an employee to the new employees array but I cannot figure out how to only push an unique list.
My final array is a 2d array so that can be setValues() back into a column in the Google sheet.
function queryEmployees(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lRow = sh.getLastRow();
var data = sh.getRange(1,1,lRow,2).getValues();
var employees = [];
for(i=0;i<data.length;i++){
if(data[i][0]==='Team member evaluated'){
if(employees.indexOf([data[i][1]])===-1){
employees.push([data[i][1]]);
}
}
}
Logger.log(employees);
Logger.log(employees.length);
SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]
.getRange(1,1,employees.length,1).setValues(employees);
}
IndexOf does not work with objects in arrays without your rewriting the function or writing your own. It works fine with strings, though. So a simple fix is to create a parallel array of strings, which allows us to keep your code almost intact. Thus, add,
var employeesIndex=[];
after your
var employees=[]
change the condition on your inner "if" clause to
(employeesIndex.indexOf(data[i][1])===-1)
and within that if block add a line to update the index
employeesIndex.push(data[i][1]);
That way the index tracks duplicates for you while your employees array contains arrays like you need.

Organise array push order

I've got an array. I push items multiple times into this array using a function. Below is an simplified version of the code.
var arr = [];
function pushItems(i){
//do something with i
var abc = "string"
arr.push(abc);
//do something with i
var xyz = "string"
arr.push(xyz);
}
Sometimes abc value is pushed before xyz. Sometimes xyz gets pushed before abc value. My question is how do I always have the abc value ahead of 'xyz' value?
So basically I need the array values to be [abc1, xyz1, abc2, xyz2, abc3, xyz3, ...] so on. How do I order the push accordingly?
This is wrong. According to the specification of this method:
The push() method adds one or more elements to the end of an array and
returns the new length of the array.
Please have a look here.
For a more formal approach please see the ECMAScript specification here.
The arguments are appended to the end of the array, in the order in
which they appear. The new length of the array is returned as the
result of the call.
Update
But even if the elements are added at the end of the array, I'm
looking a way of ordering my array.
You can use the sort function for this reason passing to it an appropriate function that will do the compare. For instance, let we have the following array
var array = [4,1,2,5,3];
and we want to order it in a descending order, we could do this like below:
var array = array.sort(function(a,b){ return b-a; });
Since you need your base64-strings to be in an arbitrary order in the array, sort them by an identifier you define.
var firstObj = {id: 0, base64: 'asdf'}
var secondObj = {id: 1, base64: 'qwer'}
var arr = []
// do stuff
// callback needs to have something along these lines:
function base64isLoaded(obj){
arr[obj.id] = obj.base64;
}
Now the 'front' image (as you gave this as example) can be given id: 0, so it ends up in the '0' spot of the array. I can't really help more without more information about how your code is structured.
EDIT: From your comment ("passing multiple items into pushItems"), I am going to assume that i (the argument) is an array and you iterate this array to transform each element into a base64 encoded string. You then want these encoded strings added to arr in the same order, correct?
easily done, simply make i an array of objects:
var i = [{source: 'abc'}, {source: 'xyz'}];
pushItems(i){
for(var c = 0; c < i.length; c++){
makeIntoBase64(i[c]);
}
}
makeIntoBase64(obj){
// this is whatever function that transforms it and takes a callback when it is done
transform(obj.source, function(result){ //pass the source to be encoded
//result should be base64 encoded string
obj.encoded = result;
});
}
after all this, the array i has objects with both .source and .encoded. If you need to know when ALL encoding is done, create a counter and add one to it in the transform callback, and check if counter === i.length every time. When it is, you know you have loaded all base64 strings and can run another function, adding these images to your catalogue or whatever else you need this for :)

How to make an array from JSON?

Couldn't think of better title.
Important to note: I'm new to js and I guess its the reason I can't figure it out by myself.
I have a JSON array returned from a database, the JSON array represent a set of points.
Example of the JSON array:
var JSON_array = [{lat:1,lng:2}, {lat:1,lng:3},{lat:2,lng:3}...]
I want to make a different array whose elements will be a function and the variables of the function will be the elements from the JSON array, like so:
var coordinates = [
new google.maps.LatLng(1, 2),
new google.maps.LatLng(1, 3),
new google.maps.LatLng(2, 3),
....
];
I made a function using forEach that counts the elements of the JSON array (for learning and trying to find a way to what I want) but I cant think of a way make the array mentioned above.
You could use Array map method:
var coordinates = JSON_array.map(function(coordinate) {
return new google.maps.LatLng(coordinate.lat, coordinate.lng);
})
This method gives you an new array based on (1) the original array and (2) how you deal with each element. Here's more detailed doc for the method.
you can also use regular for loop
coordinates = [];
for(var i=0;i<JSON_array.length;i++){
coordinates.push(new google.maps.LatLng(JSON_array[i].lat,JSON_array[i].lng));
}
For mapping element from one array to another you can use Array.prototype.map function like
var JSON_array = [{lat:1,lng:2}, {lat:1,lng:3},{lat:2,lng:3}...];
var coordinates = JSON_array.map(function(el){ return new google.maps.LatLng(el.lat, el.lng)});
As Grundy commented you can just do:
coordinates = JSON_array.map(function(x) {
return new google.maps.LatLng(x.lat, x.lng);
});
You might want to get your nomenclature straight though, this has nothing to do with JSON.

Best way to compare two json arrays and make changes to the position

I have two javascript JSON arrays as follows:
this.BicyclePartsOLD;
this.BicyclePartsNEW;
So basically both have an attribute "ListOrder". The OLD is ordered by ListOrder from 1 to n items.
The NEW one is modified but had the same records as BicyclePartsOLD, so OLD needs to get updated from NEW. If someone changed ListOrder from 1 to 3 in NEW I need to update the OLD list to have that value to 3 and make ListOrder 2 = 1, ListOrder 3 = 2.
I am trying to do it the following way but I am stuck on the best way to set the ListOrder to the new numbers:
for(var i = 0; i < this.BicyclePartsOLD.length; i++)
{
for(var j = 0; j < this.BicyclePartsNEW.length; j++)
{
if(this.BicyclePartsOLD[i].PartNumber === this.BicyclePartsNEW[j].PartNumber)
{
this.BicyclePartsOLD[i].ListOrder = this.BicyclePartsNEW[j].ListOrder;
//NOT Sure how to reorder BicyclePartsOLD here, there will be another
//item with the same ListOrder at this point.
}
}
}
Any advices that would lead me into the correct direction would be much appreciated.
Thinking out of the box, instead of having 2 arrays with the same data but totally unrelated in terms of objects, why not create 2 arrays, both containing the same objects? That way, editing an object makes it look like you're editing it in both places.
First of all, you can have 2 arrays but both point to the same objects:
Array1 -> [{foo:'bar'},{baz:'bam'}]
Array2 -> [{baz:'bam'},{foo:'bar'}]
The object with the foo in the first array can be the same exact object with the foo on the other array (I mean the same object instance, not just because they have the same properties). So editing one will basically look as if they changed in both places.
So with that concept, you can just do a slice() on the NEW array to give you a 1-level copy of the array. Basically, it's the same exact items in a different array container. You can then sort the newly sliced array however you want it.
this.BicyclePartsOLD = this.BicyclePartsNEW.slice().sort(function(){...});
Now to avoid repeatedly slicing like my first solution, I suggest you create both OLD and NEW arrays first. Then when you add an entry, create an object with your data and push that object into both arrays, that way both arrays hold the same object, and editing it will reflect on both arrays.
Something like this:
var OLD = [];
var NEW = [];
// Adding an entry
var newItem = {}
OLD.push(newItem);
NEW.push(newItem);
//Editing that item should reflect on both arrays, since they're the same
OLD[0].someProperty = 'someValue';
console.log(OLD[0].someProperty); // someValue
console.log(NEW[0].someProperty); // someValue
// An item only on OLD
var oldItem = {};
OLD.push(oldItem);
// An item only on OLD
var yetAnotherOldItem = {};
OLD.push(yetAnotherOldItem);
// Let's bring one of those old items to NEW and edit it
NEW.push(OLD[2]);
OLD[2].revived = 'I feel new!';
// Should be in both arrays, but in different indices (since there's the second OLD item)
console.log(OLD[2].revived); // someValue
console.log(NEW[1].revived); // someValue

Categories