Convert multidimensional array to array of objects in javascript - javascript

I have a multidimensional array (retdata[R][C]) that basically looks like a spreadsheet of cells. R represents the rows, C the columns. I want to create an array of objects so that I get the following
[{retdata[1][1]:retdata[2][1],retdata[1][2]:retdata[2][2],retdata[1][3]:retdata[2][3] },
{retdata[1][1]:retdata[3][1],retdata[1][2]:retdata[3][2],retdata[1][3]:retdata[3][3] },
{retdata[1][1]:retdata[4][1],retdata[1][2]:retdata[4][2],retdata[1][3]:retdata[4][3] },
etc...
]
The resulting array should be:
[{"Col1":"dataR2C1","Col2":"dataR2C2", "Col3":"dataR2C3"},
{"Col1":"dataR3C1","Col2":"dataR3C2", "Col3":"dataR3C3"},
{"Col1":"dataR4C1","Col2":"dataR4C2", "Col3":"dataR4C3"},
etc...
]
I have tried a number of options without success. Any help would be greatly appreciated.
Here is one example I have used but it id not serializing the objects properly.
var TABLE = [];
for (var i=2; i<=rows; i++) {
var ROW = {};
for (var j=1; j<=columns; j++){
name = retdata[1][j].toString;
value = retdata[i][j].toString;
ROW += {name: value}
}
TABLE += ROW;
}

This is like a CSV-parser, the first row of your table are the keys for the line-objects. Your function would work, but you need to correct your array indices: they always start at 0, running up to n-1. Also, you need to learn a bit JavaScript syntax:
something.toString does not call the toString function on that value, but gets that function (it's just an object).
You don't need toString at all - where needed, values are automatically casted
You can't add key-value-pairs to object with a simple operator. You will need to assign the value to that property of an object, with the bracket notation. The += operator would have casted the values to strings and concatenated them.
It's the same with arrays. You could use the .push() method, or just assign to a numerical key - the javascript array object will automatically update its length.
var retdata = […];
var table = [],
keys = retdata.shift(); // get & remove the first row
for (var i=0; i<retdata.length; i++) {
var row = {};
for (var j=0; j<retdata[i].length; j++)
row[ keys[j] ] = retdata[i][j];
table[i] = row;
}

Thank you Bergi. Here is my final solution:
var TABLE = [];
for (var i=2; i<=rows; i++) {
var ROW = {};
for (var j=1; j<=columns; j++){
ROW [retdata[1][j]] = retdata[i][j];
}
TABLE[i]= ROW;
}
which works. The shift did not work as expected but above code is just what I needed. Thanks!

Related

Assigning to multidimensional arrays javascript

I have arrays within objects full of false values.
var drumOn = {}, bassOn = {}, synthOn = {}, keysOn = {};
var fal = [];
for(var j=0; j<16; j++){
fal.push(false);
}
for(var j=0; j<0; j++){
drumOn['s'+j] = (fal);
bassOn['s'+j] = (fal);
synthOn['s'+j] = (fal);
keysOn['s'+j] = (fal);
}
then later I try adding one true value to one array
drumOn['s'+ 0][0] = true;
This adds a true value to the first element of all the arrays within drumOn and within the other objects too.
The only other thing I'm doing with these objects is checking
if(bassOn['s' + i][j])
I was doing this with arrays within arrays and I had the same problem.
This is crazy, I've tried so many things but it makes no sense.
Copying array by value in JavaScript
for(var j=0; j<0; j++){
drumOn['s'+j] = fal.slice();
bassOn['s'+j] = fal.slice();
synthOn['s'+j] = fal.slice();
keysOn['s'+j] = fal.slice();
}
slice returns a copy of the array. In your example, all of the items are pointing to the same original array fal. You need to duplicate it.

How to work with multidimensional array when the number of dimension is variable?

Hello stackoverflow members.
I come with the following problem:
To start we have
var myArray = [[array1],[array2],[array3],[arrayN],...];
where each array is filled with a known number of strings such as
var array1 = ["a","b"], array2 = ["1","2"], array3=["&","é"];....
and so on.
I'm looking for a method to get this result:
expected result ===> a1&;a1é;a2&;a2é;b1&;b1é;b2&;b2é; ....
If the number of dimension were fixed I could use for loops to iterate and build the result, BUT here the problem is that I want to be able to enter N arrays in the main array myArray and by doing so, I change the depth of the nested loops.
If not do you have some ideas to put me on the track of the solution to this?
Thanks!
EDIT by the way this is what i experimented:
for (i=0; i<myArray[0].length; i++){
for (var j =0; j<myArray[1].length; i++){
for(var k = 0; k<myArray[2].length; k++{
console.log(i+j+k);
}
}
}
BTW i can't find a way to describe a function which would nest N for loops where N is myArray.length + 1 (the number of arrays in myArray).
EDIT: i found an iterative way of doing it and wanted to share the solution:JSFiddle
To get a flat list of all cells, something like the following recursive function should work (if you have a non-empty array of arrays, and all array items are strings):
function makeFlatList(inputArray) {
if (inputArray.length == 1) { // if this array has only one array inside
return inputArray[0]; // return the array inside
} else {
var outArr = [];
var arrayShifted = inputArray.slice(1); // remove first subarray from inputarray
var arrayShiftedFlat = makeFlatList(arrayShifted); // recursive call
for (var i=0; i<inputArray[0].length ; i++) { // loop over first array
for (var j=0; j<arrayShiftedFlat.length; j++) {
outArr.push(inputArray[0][i]+arrayShiftedFlat[j]); // add items to outArr
}
}
return outArr;
}
}
Working JSBin here

Sorting Array but keeping Original Index

I have an array of indexes, called indexSelected. There is also an array of objects called weather. I have put all of the Site Names that that I am dealing with into an array called stationName. I want to sort this array alphabetically whilst keeping the original indexes for that I can refer back to the other properties associated with object. I have tried the method below, however, I cannot seem to get it to work.
var stationName=[];
for (var i=0; i<indexSelected.length; i++) {
stationName.push(weather[indexSelected[i]]["Site Name"]);
}
var copyStationName = stationName.slice(0)
var sortedStationName = stationName.sort();
var originalIndex=[];
for (var i=0; i<stationName.length; i++) {
originalIndex.push(copyStationName.indexOf(sortedStationName[i]))
}
var station=[];
for (var i=0; i<indexSelected.length; i++) {
station.push(weather[originalIndex[i]]["Site Name"]);
}
This station array was to check that the originalIndexes array was correct. It isn't, and I don't know why. I would appreciate some help, or another way to sort this array. I'm looking to put all of the data into a table, sort alphabetically by site name. Thanks
Build an array of objects that carry both the name and index, then use a custom comparison function for the sort. E.g.
var stationInfo = [];
for (var i=0; i<indexSelected.length; i++) {
var idx = indexSelected[i];
stationInfo.push({name: weather[idx]["Site Name"], idx: idx);
}
stationInfo.sort(function(a, b) {
// a & b are the array items (info objects) created above, so make 'em
// point at the `name` property we want to sort by
a = a.name;
b = b.name;
// ... then return -1/0/1 to reflect relative ordering
return a < b ? -1 : (a > b ? 1 : 0);
})
// output a name + index pair
console.log(stationInfo[0].name, stationInfo[0].idx);

how to generate arrays automatically in javascript?

I want to make a loop that makes arrays automatically and assign the values to it.
The problem is how to generate the array itself automatically.
for(var attGetter=1; attGetter <= num; attGetter++){
var catesArray1 = new Array();
for(var atttGetterArray=1; atttGetterArray <= series; attGetterArray++){
idOfInput = "cate"+chartGetter+"_series"+attGetterArray;
catesArray1.push($("#"+idOfInput).val());
}
}
I want the loop to generate the array itself automatically like
catesArray1
catesArray2
catesArray3
and so on..
You need an object or an array to hold the multiple arrays you wish to create. Maybe something you are looking for is like the following?
var arrayHolder = new Array();
for(var attGetter=1; attGetter <= num; attGetter++){
var catesArray = new Array();
for(var attGetterArray=1; atttGetterArray <= series; attGetterArray++){
idOfInput = "cate"+chartGetter+"_series"+attGetterArray;
catesArray.push($("#"+idOfInput).val());
}
arrayHolder.push(catesArray);
}
If you want the arrays to be in global namespace, You can try
window['catesArray' + attGetter] = [];
...
window['catesArray' + attGetter].push(...)
Else you can create a hash object and use it to hold the reference
var obj = {};
.....
obj['catesArray' + attGetter] = [];
.....
obj['catesArray' + attGetter].push(...)
In that case you will have to create one new array that holds all the cacatesArrays from first for loop
var catesArrayContainer = new Array(); //<<<---------------------
for(var attGetter=1; attGetter <= num; attGetter++){
var catesArray = new Array();
for(var atttGetterArray=1; atttGetterArray <= series; attGetterArray++){
idOfInput = "cate"+chartGetter+"_series"+attGetterArray;
catesArray.push($("#"+idOfInput).val());
}
catesArrayContainer.push(catesArray); //<<<--------------------
}
EDIT :
This happens because the scope of variable catesArray1 was limited. When the loop enters next iteration the catesArray1 gets reinitialized, thus losing all the previously stored values...
Now in the code I have posted, we are storing every instance of catesArray1 in another array, and your values persist out side of the for loop
You can do something like this for 4 arrays of 5 elements each
yourarray=[];
for (i = 0; i <4; i++) {
temparray=[];
for (j = 0; j < 5; j++) {
temparray.push($('#'+whateverID+'_'+i+'_'+j)) //your values here
}
yourarray.push(temparray);
}
Check it on this JSFiddle. open chrome console to see array
If you want to create array within loop from index
You can use eval to evaluate javascript from strings but i wont use that unless there is no other way. you can see both above and eval method in this Fiddle. Open Chrome console to see array values
Just a comparison of using eval and 2D array
Open console in chrome while you run this jsFiddle and you will see the difference in eval and 2darray in context of this question.
You should assign them to an object. In this case, make an object variable before the first for-loop to hold all arrays:
var allArrays = {};
for(var attGetter=1; attGetter <= num; attGetter++){
var currentArray = allArrays['catesArray' + attGetter] = new Array();
for(var atttGetterArray=1; atttGetterArray <= series; attGetterArray++){
idOfInput = "cate"+chartGetter+"_series"+attGetterArray;
currentArray.push($("#"+idOfInput).val());
}
}
Instead of attempting to create & allocate dynamically named variables, I would think of this more of an array of array's if you will. In other words, create an array that holds all of the arrays you want:
var collections = []; // Literal notation for creating an array in JS
From here, it's a matter of making each value you create within this array its own array:
var n = 10; // Total amount of arrays you want
for (var i = 0; i < n; i++) {
var values = [];
// Have another loop that fills in the values array as expected
collections.push(values); // Each element at collections[i] is its own array.
}
If you truly need named elements, you could potentially do something very similar with just an object {} instead, and refer to each element by a name you create.
var collections = {}; // Literal notation for an object in JS
var n = 10; // Total amount of arrays you want
for (var i = 0; i < n; i++) {
var values = []; // Literal notation for an array in JS
// Fill in the values array as desired
var name = 'arr' + i; // How you'll refer to it in the object
collections[name] = values;
}
I suggest the former though, since it does not sound like you need to have explicit names on your arrays, but just want multiple layers of arrays.

Javascript for loop var "i" is treated as a string?

I am using Titanium to build some mobile apps and I noticed that this will give a result that I wasn't expecting.
data = ['a','b', 'c','d'];
for (var i in data){
Ti.API.debug(i+1);
};
This will print: 01,11,12,13
Is this something particular to Titanium or is it generally in Javascript?
Why isn't 'i' being treated as an integer? I am very confused.
Thanks for your help.
This doesn't directly answer your question, but if you are looping through an array you should not use for (var i in data). This loops through all members of an object, including methods, properties, etc.
What you want to do is this:
for (var i=0, item; i<data.length; i++) {
item = data[i];
}
data is an array, so you use a for loop, not a for-in loop:
var data = [ ... ];
var i;
for ( i = 0; i < data.length; i += 1 ) {
Ti.API.debug( i + 1 );
}
Alternatively, you can use the forEach array method:
data.forEach( function ( val, i ) {
Ti.API.debug( i + 1 );
});
The reason why you see this behavior is that the type of i when using a for-in over an array is string not int. Hence the + is doing string concatenation and not addition. If you want it to be the numerical value then use a for loop
for (var i = 0; i < data.length; i++) {
Ti.API.debug(i + 1);
}
Try this:
data = ['a','b', 'c','d'];
for (var i in data){
Ti.API.debug(i*1+1);
};
Multiplying i x 1 will force it to recognize it as numeric.
Try this:
Ti.API.debug(parseInt(i)+1);
You can do
data = ['a','b', 'c','d'];
for (var i in data){
console.log(parseInt(i)+1);
};
But it is not recommended. Because in Javascript for..in loop is for key:value pairs (Objects). So if use it with an array each index is converted to string as key.
so always use for(i = 0; i < length; i++) with arrays.
This is because javascript handles for-each loop this way.
In other languages for(i in datas) will loop through each data.
But in javascript the i will have index value instead of data. so you have to get data by datas[i].

Categories

Resources