Creating and Accessing 2-dimensional arrays in javascript - javascript

I'm confused about how to create and access 2-dimensional arrays in javascript. Below is an array declaration in which I'm storing names of people and then the src for their image. When I try to access myArray[0][0] element I get 'D' and when I try to access myArray[0,0], I get Donald Duck. How can I access the img src myArray[0][0] = "assets/scrybe.jpg" ?
JS code:
var myArray = new Array(1);
myArray[0] = "Donald Duck";
myArray[1] = "Winnie Pooh";
myArray[2] = "Komal Waseem";
myArray[3] = "Hockey";
myArray[4] = "Basketball";
myArray[5] = "Shooting";
myArray[6] = "Mickey Mouse";
myArray[0][0] = "assets/scrybe.jpg";
myArray[1][0] = "assets/scrybe.jpg";
myArray[2][0] = "assets/scrybe.jpg";
myArray[3][0] = "assets/scrybe.jpg";
myArray[4][0] = "assets/scrybe.jpg";
myArray[5][0] = "assets/scrybe.jpg";
myArray[6][0] = "assets/scrybe.jpg";

Firstly, to create an array, it's better to use the square bracket notation ( [] ):
var myArray = [];
This is the way you emulate a multi-demensional array in JavaScript. It's one or more arrays inside an array.
var myArray = [
[], [] // two arrays
];
If you're asking if there's a way to declare an array as multi-dimensional, then no, there isn't. You can access them like this:
myArray[0][0]; // the 1st element of the first array in myArray
myArray[1][1]; // the 2nd element of the second array in myArray
Here is the code you were probably looking for:
var myArray = [
["Donald Duck", "assets/scrybe.jpg"],
["Winnie Pooh", "assets/scrybe.jpg"],
["Komal Waseem", "assets/scrybe.jpg"]
[/* and so on...*/]
];
But since you're giving all the names the same URL, then you can use a for loop instead to do this faster:
for (var i = 0; i < myArray.length; i++) {
myArray[i][1] = "assets/scrybe.jpg";
}

Perhaps what you really want is an array of objects:
var myArrray = [
{ name: "Donald Duck", image: "assets/scrybe.jpg" },
{ name: "Winnie Pooh", image: "assets/scrybe.jpg" },
// ...
];
JavaScript doesn't really have 2-dimensional arrays, as such. What you can do is create an array such that each element is also an array.
var twoDim = [ [], [], [], [], [] ];
In your case, however, I don't think that structure will help much.

No it cannot be done like that. Must either do:
var myArray = new Array(1);
myArray[0] = new Array(1);
myArray[0][0] = "Donald Duck";
myArray[0][1] = "assets/scrybe.jpg";
Or use JS syntax
var myJSObj = {"Donald" :"assets/scrybe.jpg", "Donald2": "assets/scrybe2.jpg" };

I had the same issues and I used minBy from Lodash
https://lodash.com/docs/4.17.4#minBy
var objects = [{ 'n': 1 }, { 'n': 2 }];
_.minBy(objects, function(o) { return o.n; });
// => { 'n': 1 }
// The `_.property` iteratee shorthand.
_.minBy(objects, 'n');
// => { 'n': 1 }

Related

how can i transmission array to object with lodash?

I have an array like as below
var arr = [ 'type=A', 'day=45' ];
var trans = { 'type': 'A', 'day': 45 }
Please write easiest and most efficient way :)
You could split the string and check if the value isNaN for string or take the numerical value.
var array = [ 'type=A', 'day=45', 'bar=0' ],
object = Object.create(null);
array.forEach(function (a) {
var p = a.split('=');
object[p[0]] = isNaN(p[1]) ? p[1] : +p[1];
});
console.log(object);
The solution using Array.prototype.reduce() function:
var arr = [ 'type=A', 'day=45' ],
trans = arr.reduce(function(r, s){
var parts = s.split('=');
r[parts[0]] = isNaN(parts[1]) ? parts[1] : +parts[1];
return r;
}, {});
console.log(trans);
Iterate over each item in the array
Split on =
Add value to object, at key index
var arr = [ 'type=A', 'day=45' ];
var object = {};
for (var i = 0; i < arr.length; i++) {
var currentItem = arr[i].split('=');
var key = currentItem[0];
var value = currentItem[1];
object[key] = value;
}
console.log(object);
There's probably a million different ways to this, this way uses two different functions. the _.map() call runs on every element, splitting (and parsing) the element (if it matches a character regex). It then uses Lodash's .fromPairs function, which converts an array made up of 2 element arrays to return an object.
var arr = ['type=A', 'day=45'];
var obj = _.fromPairs(_.map(arr, function(item) {
var parts = item.split('=');
var digits = /^\d+$/;
if (digits.test(parts[1])) parts[1] = parseInt(parts[1]);
return parts;
}));
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Why this array producer code doesn't work as it shows?

I have used some code as bellow to produce new array from tow arrays :
var arr1 = [['wo','ss'],['er','me'], ['lo','to']];
var arr2 = [['mine','yours'],['from', 'theme']];
var arr3 = [];
var temp = [];
//this will be an array of arrays that every index is arr2 + one index from arr1
var end = [];
arr1.forEach(function(item) {
temp = arr2;
temp.push(item);
end.push(temp);
})
console.log(end)
But after the result is not my desired and is not logical
[
['mine','yours'], ['from','theme'], ['wo', 'ss'],
['mine', 'yours], ['from','theme'], ['er', 'me'],
['mine', 'yours], ['from','theme'], ['lo', 'to']
]
You must clone the arr2 for each iteration defining temp as new array each time
var arr1 = [['wo','ss'],['er','me'], ['lo','to']];
var arr2 = [['mine','yours'],['from', 'theme']];
var arr3 = [];
var end = [] //this will be an array of arrays that every index is arr2 + one index from arr1
arr1.forEach(function(item) {
var temp = arr2.slice();
temp.push(item);
end.push(temp);
})
console.log(end);
This code works as you expected
In your code Array#push method will push values to arr2 which update the array(since temp is reference to array arr2) on each iteration.
Use Array#concat method which generates a new concatenated array although Array#map can be used for generating the array.
var arr1 = [
['wo', 'ss'],
['er', 'me'],
['lo', 'to']
];
var arr2 = [
['mine', 'yours'],
['from', 'theme']
];
var end = arr1.map(function(item) {
return arr2.concat([item]);
})
console.log(JSON.stringify(end))
UPDATE : Currently it creates the reference to the parent array updating one will change other. if you want a new array with the element then do it with Array#map and Array#slice methods .
var arr1 = [
['wo', 'ss'],
['er', 'me'],
['lo', 'to']
];
var arr2 = [
['mine', 'yours'],
['from', 'theme']
];
var end = arr1.map(function(item) {
return arr2.map(function(v) {
return v.slice();
}).concat([item.slice()]);
})
console.log(end)

Is this javascript declaration an array or some kind of object

Can someone please explain how the following javascript code:
var temp = {};
temp[0] = "a"
temp[1] = "b"
temp[2] = "c"
if different from an array like
var temp = new Array();
or
var temp = []
I don't really understand if the first example "temp = {}" can be considered an array or is it some kind of object?
var temp = {}; is an object with representation like Object {0: "a", 1: "b", 2: "c"}
var temp = [] is an array with representation like ["a", "b", "c"]
while var temp = new Array(); is again the same thing like temp = []
More detailed information here What’s the difference between "Array()" and "[]" while declaring a JavaScript array?
The first one creates an object:
var temp = {};
The second one creates an array:
var temp = new Array();
In any case you can access them as they are an array:
var temp = {};
temp[1]="in object";
console.log(temp[1]);
same as
var temp = []
temp[1]="in array";
console.log(temp[1]);

Combine Arrays in Order JavaScript

I have a few arrrays which I am trying to combine in a certain order. For example, lets say I have three arrays:
var arrayOne = [1a, 1b, 1c];
var arrayTwo = [2a, 2b, 2c];
var arrayThree [3a, 3b, 3c];
how would I get something like this?
var combinedArray = [1a, 2a, 3a, 1b, 2b, 3b, 1c, 2c, 3c]
EDIT
Ok, I am going to add a little more to my story here since I have gotten some great responses and answers from everyone. Maybe this will be clearer. I have a SharePoint list which I am getting all of my information from. I am using SPServices to get my data from the list. I am also getting the version history of each list item and placing them into arrays so I can pull the data out of the SPServices loop and use it outside of the SharePoint stuff so I can try to order and display it as I want. (Please do not move this to SharePoint ).
This is all going to have to happen at runtime. So here is the first part. I am declaring global variables for each one of my list items:
var proModified6 = new Array();
var proHistory = new Array();
var assignedTo = new Array();
var startDate = new Array();
var endDate = new Array();
var status = new Array();
var project = new Array();
var history = new Array();
var listItems = new Array();
var regex = new RegExp("");
var i = 0;
Then I am filling the arrays with the SharePoint list info ( I am not going to put them all but each has a call like this one)
$().SPServices({
operation: "GetVersionCollection",
async: false,
webURL: "http://devchrisl01/test",
strlistID: "NewProjects",
strlistItemID: proID[i],
strFieldName: "Title",
completefunc: function (xdata, Status) {
$(xdata.responseText).find("Version").each(function() {
//alert(xdata.responseXML.xml);
var xitem = $(this);
var ID = xitem.attr('ID');
var Project = xitem.attr('Title');
var Modified = xitem.attr('Modified').split('T')[0];
var ModifiedTime = xitem.attr('Modified').substring(11, 19);
//var modifiedUl = "<td><b>" + Modified + " " + ModifiedTime + "</b></td>";
//$('#versionList'+i+'').append(modifiedUl);
project.push(Project);
proModified2.push(Modified + ModifiedTime)
// just looking at my data here not really part of my problem
var data = "<tr><td><b>" + Modified + " " + ModifiedTime + "</b></td><td>" + Project + "</td></tr>";
$('#versionList'+i+'').append(data);
});
}
});
After is where my question has come into play. I am getting all of my data back I need. I have not found a better way to store all of the list information and pull it out of the SPServices besides using an array for each. The kicker is I am not going to know how many arrays there are going to be or how long. Eventually this is going to be dynamic. (PAIN IN THE ASS ) so here are the arrays:
var modifiedDate = [proModified1, proModified2, proModified3, proModified4, proModified5, proModified6];
var projectHistory = [history];
var projectTitle = [project];
var projectAssignedTo = [assignedTo];
var projectStartDate = [startDate];
var projectEndDate = [endDate];
var projectStatus = [status];
Each one is going to be different. There is not going to be the same amount of them either for each user. I have just made my list static to build on first. List dynamics will be another question later :0
Is there going to be a way for me to do with these arrays like I asked in my simple example? See why I went simple first lol.
Edit: Updated comparator as Salmon pointed out that it should return -1, 0 or 1.
Try below,
var arrayOne = ["1a", "1b", "1c"];
var arrayTwo = ["2a", "2b", "2c"];
var arrayThree = ["3a", "3b", "3c"];
var combinedArray = arrayOne
.concat(arrayTwo, arrayThree) //Concatenate the array.. can add any number of arrays
.sort(function(a, b) { //Custom comparator for your data
var a1 = a.charAt(1);
var b1 = b.charAt(1);
if (a1 == b1) return 0;
if (a1 < b1) return -1;
return 1;
});
Note: The custom comparator function is very specific to your data. Update the function as you need.
DEMO
From my understanding, you're looking for a zip function, like in python. There's no such built-in in javascript, but it's easy to write, for example:
zip = function() {
var
args = [].slice.call(arguments, 0),
len = Math.max.apply(Math, args.map(function(x) { return x.length })),
out = [];
for (var i = 0; i < len; i++)
out.push(args.map(function(x) { return x[i] }));
return out;
}
Applied to your arrays
var arrayOne = ["1a", "1b", "1c"];
var arrayTwo = ["2a", "2b", "2c"];
var arrayThree = ["3a", "3b", "3c"];
zipped = zip(arrayOne, arrayTwo, arrayThree);
this creates a nested array:
[["1a", "2a", "3a"], ["1b", "2b", "3b"], ["1c", "2c", "3c"]]
which you can use as is or convert to a flat one:
flat = [].concat.apply([], zipped)
If the length of the three arrays will always be the same of each other:
var arrayOne = ["1a", "1b", "1c"];
var arrayTwo = ["2a", "2b", "2c"];
var arrayThree = ["3a", "3b", "3c"];
var newArray = [];
for (var i = 0, len = arrayOne.length; i < len; i++) {
newArray.push(arrayOne[i], arrayTwo[i], arrayThree[i]);
}
console.log(newArray); //1a,2a,3a,1b,2b,3b,1c,2c,3c
But if your arrays won't always be the same length, we will need to use the greatest length of the three arrays and skip missing indexes, so it will be like this:
var arrayOne = ["1a", "1b", "1c", "1d"];
var arrayTwo = ["2a", "2b", "2c"];
var arrayThree = ["3a", "3b"];
var newArray = [];
var len = Math.max(arrayOne.length, arrayTwo.length, arrayThree.length);
for (var i = 0; i < len; i++) {
if (i in arrayOne) {
newArray.push(arrayOne[i]);
}
if (i in arrayTwo) {
newArray.push(arrayTwo[i]);
}
if (i in arrayThree) {
newArray.push(arrayThree[i]);
}
}
console.log(newArray); //1a,2a,3a,1b,2b,3b,1c,2c,1d
The reason to use i in arr (as difference of other checks), is because this will allow you to keep any falsish value 0,"",false,null,undefined,NaN intact. Otherwise it will be very hard to leave them alone (specially undefined values inside your array)
Performance tests between my answer and the currently most upvoted answer
I'd suggest using the default JS sort() method with a callback of some kind. If the elements if the array are all like /[0-9][a-z]/, this will give you the desired result:
//concat arrays first, of course
function specialSort(a,b)
{
if(a[1] < b[1])
{
return -1;
}
if(a[1] > b[1])
{
return 1;
}
return 0;
}
//using wsanville's expample: combinedArray = ["1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c"]
combinedArray = combinedArray.sort(specialSort);
//result: combinedArray = ["1a", 2a", "3a", "1b", "2b", "3b", "1c", "2c", "3c"]
Hope this works for you...
You can simply do:
var arrayOne = ["1a", "1b", "1c"];
var arrayTwo = ["2a", "2b", "2c", "2d", "2e"];
var arrayThree = ["3a", "3b", "3c", "3d"];
var combinedArray = [];
for (var i = 0, j = Math.max(arrayOne.length, arrayTwo.length, arrayThree.length); i < j; i++) {
if (arrayOne.length) combinedArray.push(arrayOne.shift());
if (arrayTwo.length) combinedArray.push(arrayTwo.shift());
if (arrayThree.length) combinedArray.push(arrayThree.shift());
}
alert(combinedArray.join(", "));​
This should probably work for variable length arrays. Demo here.

Group array items based on variable javascript

I have an array that is created dynamic from an xml document looking something like this:
myArray[0] = [1,The Melting Pot,A]
myArray[1] = [5,Mama's MexicanKitchen,C]
myArray[2] = [6,Wingdome,D]
myArray[3] = [7,Piroshky Piroshky,D]
myArray[4] = [4,Crab Pot,F]
myArray[5] = [2,Ipanema Grill,G]
myArray[6] = [0,Pan Africa Market,Z]
This array is created within a for loop and could contain whatever based on the xml document
What I need to accomplish is grouping the items from this array based on the letters so that all array objects that have the letter A in them get stored in another array as this
other['A'] = ['item 1', 'item 2', 'item 3'];
other['B'] = ['item 4', 'item 5'];
other['C'] = ['item 6'];
To clarify I need to sort out items based on variables from within the array, in this case the letters so that all array objects containing the letter A goes under the new array by letter
Thanks for any help!
You shouldn't use arrays with non-integer indexes. Your other variable should be a plain object rather than an array. (It does work with arrays, but it's not the best option.)
// assume myArray is already declared and populated as per the question
var other = {},
letter,
i;
for (i=0; i < myArray.length; i++) {
letter = myArray[i][2];
// if other doesn't already have a property for the current letter
// create it and assign it to a new empty array
if (!(letter in other))
other[letter] = [];
other[letter].push(myArray[i]);
}
Given an item in myArray [1,"The Melting Pot","A"], your example doesn't make it clear whether you want to store that whole thing in other or just the string field in the second array position - your example output only has strings but they don't match your strings in myArray. My code originally stored just the string part by saying other[letter].push(myArray[i][1]);, but some anonymous person has edited my post to change it to other[letter].push(myArray[i]); which stores all of [1,"The Melting Pot","A"]. Up to you to figure out what you want to do there, I've given you the basic code you need.
Try groupBy function offered by http://underscorejs.org/#groupBy
_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
Result => {1: [1.3], 2: [2.1, 2.4]}
You have to create an empty JavaScript object and assign an array to it for each letter.
var object = {};
for ( var x = 0; x < myArray.length; x++ )
{
var letter = myArray[x][2];
// create array for this letter if it doesn't exist
if ( ! object[letter] )
{
object[letter] = [];
}
object[ myArray[x][2] ].push[ myArray[x] ];
}
Demo fiddle here.
This code will work for your example.
var other = Object.create(null), // you can safely use in opeator.
letter,
item,
max,
i;
for (i = 0, max = myArray.length; i < max; i += 1) {
item = myArray[i];
letter = myArray[2];
// If the letter does not exist in the other dict,
// create its items list
other[letter] = other[letter] || [];
other.push(item);
}
Good ol' ES5 Array Extras are great.
var other = {};
myArray.forEach(function(n, i, ary){
other[n[2]] = n.slice(0,2);
});
Try -
var myArray = new Array();
myArray[0] = [1,"The Melting Pot,A,3,Sake House","B"];
myArray[1] = [5,"Mama's MexicanKitchen","C"];
myArray[2] = [6,"Wingdome","D"];
myArray[3] = [7,"Piroshky Piroshky","D"];
myArray[4] = [4,"Crab Pot","F"];
myArray[5] = [2,"Ipanema Grill","G"];
myArray[6] = [0,"Pan Africa Market","Z"];
var map = new Object();
for(i =0 ; i < myArray.length; i++){
var key = myArray[i][2];
if(!map[key]){
var array = new Array();
map[key] = array;
}
map[key].push(myArray[i]);
}

Categories

Resources