JavaScript: Transforming a multi-dimensional array into a two dimensional array - javascript

I have a JS array that's filled with data as follows:
var myarr = [[new Date("2011-12-01"), 389, 380.75, 382.54, 387.93],
[new Date("2011-11-30"), 382.28, 378.3, 381.29, 382.2]...]
Is there some way to only select the entire date column and the last number of each row? I'm looking for an output that's something like this:
[[new Date("2011-12-01"), 387.93],[new Date("2011-11-30"), 382.2]...]

var myCollapsedArr = [[myarr[0][0], myarr[0][myarr[0].length-1]], [myarr[1][0], myarr[1][myarr[1].length-1]];
Or in a for loop:
var myCollapsedArr = [];
for(var i = 0; i<myarr.length; i++) {
myCollapsedArr.push([myarr[i], [myarr[i][myarr[i].length-1]]);
}

Option 1 - Simple for Loop
// Create array to hold new values
var newArray = [];
// Loop through existing array and pull out data
for(var i = 0; i < myarr.length; i++) {
newArray.push([myarr[i][0], myarr[i][myarr[i].length - 1]]);
}
Here's a working fiddle to demonstrate.
Option 2 - ECMAScript 5 forEach()
// Create array to hold new values
var newArray = [];
// Loop through existing array and pull out data
myarr.forEach(function(obj) {
newArray.push([obj[0], obj[obj.length - 1]]);
});
​Here's a working fiddle to demonstrate.

Related

Filter multidimensional array by a column

I am trying to create an array that I can filter by in Google Apps Script. This works when the array is made of values I take from the columns using range.getValues(), but doesn't work when I create a similar multidimensional array using a loop.
I am trying to create the array myself as opposed to getting it from the sheet as the columns that I want are not consecutive: one is the 10th column, the next is the 1st, the next is the 3rd etc.
This works and returns the full multidimensional range filtered properly:
function RunReport(){
var errorSS = SpreadsheetApp.getActive();
var enterpriseSheet = errorSS.getSheetByName('Enterprise');
var destSheet = errorSS.getSheetByName('TestSheet');
var sheetData = [];
sheetData = enterpriseSheet.getRange(1, 1, 2000, 4).getValues();
var filtered = sheetData.filter(function(dataRow){
return dataRow[0] === 'Error';
});
Logger.log(filtered);
}
This 'works' but only returns the first 'column' of the array filtered by the 'Error value' but doesn't return the other parts of the array:
function RunReport(){
var errorSS = SpreadsheetApp.getActive();
var enterpriseSheet = errorSS.getSheetByName('Enterprise');
var destSheet = errorSS.getSheetByName('TestSheet');
var sheetData = [];
var col1 = enterpriseSheet.getRange(1, 1, enterpriseSheet.getLastRow()).getValues();
var col2 = enterpriseSheet.getRange(1, 10, enterpriseSheet.getLastRow()).getValues();
var col3 = enterpriseSheet.getRange(1, 2, enterpriseSheet.getLastRow()).getValues();
var col4 = enterpriseSheet.getRange(1, 3, enterpriseSheet.getLastRow()).getValues();
for (i = 0; i < col1.length; i++)
{
sheetData.push(col1[i],col2[i],col3[i],col4[i]) ;
}
var filtered = sheetData.filter(function(dataRow){
return dataRow[0] === 'Error';
});
Logger.log(filtered);
}
any ideas on what I am doing wrong?
Issue:
You're getting a 2D array.
You're pushing a four 1D arrays.
Solution:
You need to push 4 elements as a single array.
Modified Script:
push a single array with four elements
//sheetData.push(col1[i],col2[i],col3[i],col4[i]) ;
sheetData.push([col1[i][0],col2[i][0],col3[i][0],col4[i][0]]);
Alternatively, You can splice everything in col1:
//for(i=0 ; i<col1.length ; i++)
//{ sheetData.push(col1[i],col2[i],col3[i],col4[i]) ;}
col1.map(function(e,i){
e.splice(1,0,col2[i][0],col3[i][0],col4[i][0]);
return e;
});
Logger.log(col1);
References:
2D Array
Array#filter
Array#map
Array#Splice

Javascript 2D array getting each element

I have a 2D array that looks like:
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
I'd like to iterate through the array and take out 'V1.0' and 'V2.0' and store them in their own new array, and do the same for '1' and '2'. I need to break the data up for use with Chart.js
My loop looks like this:
var labels = [];
var data = [];
for (var i=0; i<example.length; i++) {
labels.push = (example[i][0]);
}
for (var j=0; j<example.length; j++) {
data.push = (example[0][j]);
}
I don't know how to properly get either element into their own array for use later.
You can use map to do this, and shift the result in order to remove the first occurence.
var example = [
['Version', 'Number'],
['V1.0', 1],
['V2.0', 2]
];
var result = example.map(e => e[0])
console.log(result);
From what I saw into your example the first pair of elements are the keys for your data, into your example will include them into your final arrays.
This example will generate to a dictionary with the keys Number and Version containing the corresponding values from your array.
var example = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]];
function extract(items) {
var keys = {},
version = items[0][0],
number = items[0][1];
keys[version] = [];
keys[number] = [];
return items.slice(1).reduce(function(acc, item) {
acc[version].push(item[0]);
acc[number].push(item[1]);
return acc;
}, keys);
}
var result = extract(example);
console.log(result);
From this point you can do something like:
var labels = result.Version;
var data = result.Number;
This looks like what you are trying to achieve:
for(var i=0; i<example.length; i++){
labels.push(example[i][0])
data.push(example[i][1])
}

How to separate array of comma separated string into various arrays?

What's the best way to convert this array of comma separated values
[ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on' ]
Into three arrays?
[ 'com--test', [ LFutx9mQbTTyRo4A9Re5Ilsdf4cKN4q2', ['on',
'com--fxtrimester', SEzMpW3FxkSbzL7eo5MmlkdfqkPczCl2', 'on',
'com--fxtrimester' ] LFutksdfx9mQbTTyRo4A9Re5I4cKN4q2 ] 'on']
I was trying something like:
var indexToSplit = unique.indexOf(',');
var status = unique.slice(3, indexToSplit - 1);
var use = unique.slice(2, indexToSplit - 2);
var pros = unique.slice(0, indexToSplit - 3);
console.log(pros);
But I figured that is wrong ... any help is appreciated!
You will have to loop over array and use string.split to get seperate parts.
Once you have seperate parts, you can push them to necessary array;
var d = [ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on'];
var result = [[],[],[]];
var len = 3;
d.forEach(function(str, i){
var _tmp = str.split(',');
for (var i = 0; i<len; i++){
result[i].push(_tmp[i])
}
})
console.log(result)
A little generic way.
Loop over data and split each string using comma(,)
Loop over split values and check if necessary array exists.
If not, initialise array, but you cannot do p[i] = [] as this will push to first value. You will have to also initialise all previous values. For this, you can use new Array(length). By default, if length is greater than 0, all indexes will be initialise to undefined.
Now push to necessary array. Position will be maintained.
var d = ['com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on,test'
];
var result = d.reduce(function(p, c, index) {
var _tmp = c.split(',');
for (var i = 0; i < _tmp.length; i++) {
// Check if position not defined.
if (p[i] === undefined)
// Initialize array and add default (undefined) to all elements before current element
p[i] = new Array(index);
p[i].push(_tmp[i])
}
return p;
}, [])
console.log(result)
With map this becomes:
for positions X out of 0, 1 and 2:
convert each item in the list into an array, and choose the Xth item
var start = [ 'com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on',
'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on',
'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on' ]
var out = [0,1,2].map(i =>
start.map(x => x.split(',')[i]) )
console.log(out)
Since your question does not ask for a more general case, i am safely assuming it for 3 array. We can use forEach function on array below code can be one amongst the possible solutions
var arr1 = [];
var arr2 = [];
var arr3 = [];
var x = ['com--test,LFutx9mQbTTyRo4A9Re5ksjdnfsI4cKN4q2,on', 'com--fxtrimester,SEzlksdfMpW3FxkSbzL7eo5MmqkPczCl2,on', 'com--fxtrimester,LFutx9mQbTTyRoldksfns4A9Re5I4cKN4q2,on']
x.forEach(function(data) {
var dataArray = data.split(',');
arr1.push(dataArray[0]);
arr2.push(dataArray[1]);
arr3.push(dataArray[2]);
});
console.log(arr1)
console.log(arr2)
console.log(arr3)

Javascript change format from looping into array format

I have a loop thats looping through some data and getting some fiel values from it.
for (var i = 0; i < mainData[0].main.length; i++) {
var obj = mainData[0].main[i];
var cars = obj.cars;
console.log(cars);
}
This is returning
26
65
34
12
etc
What I need is to put this in a format so it looks like this:
[26, 65, 34, 12]
How can I do this?
You could just map the result and get an array.
cars = mainData[0].main.map(a => a.cars);
ES5
cars = mainData[0].main.map(function (a) { return a.cars; });
You can try this
var result=[];
for (var i = 0; i < mainData[0].main.length; i++) {
var cars = obj.sub.cars;
result.push(cars);
}
console.log(result);
Print the array directly
If you are trying to print just the array, you can use console.log(array)instead of looping over everything in the array.
for example, assume this is the array.
var primes = [2,3,5,7];
console.log(primes);
will output [2,3,5,7]

Sort array by order according to another array

I have an object that is being returned from a database like this: [{id:1},{id:2},{id:3}]. I have another array which specified the order the first array should be sorted in, like this: [2,3,1].
I'm looking for a method or algorithm that can take in these two arrays and return [{id:2},{id:3},{id:1}]. Ideally it should be sort of efficient and not n squared.
If you want linear time, first build a hashtable from the first array and then pick items in order by looping the second one:
data = [{id:5},{id:2},{id:9}]
order = [9,5,2]
hash = {}
data.forEach(function(x) { hash[x.id] = x })
sorted = order.map(function(x) { return hash[x] })
document.write(JSON.stringify(sorted))
function sortArrayByOrderArray(arr, orderArray) {
return arr.sort(function(e1, e2) {
return orderArray.indexOf(e1.id) - orderArray.indexOf(e2.id);
});
}
console.log(sortArrayByOrderArray([{id:1},{id:2},{id:3}], [2,3,1]));
In your example, the objects are initially sorted by id, which makes the task pretty easy. But if this is not true in general, you can still sort the objects in linear time according to your array of id values.
The idea is to first make an index that maps each id value to its position, and then to insert each object in the desired position by looking up its id value in the index. This requires iterating over two arrays of length n, resulting in an overall runtime of O(n), or linear time. There is no asymptotically faster runtime because it takes linear time just to read the input array.
function objectsSortedBy(objects, keyName, sortedKeys) {
var n = objects.length,
index = new Array(n);
for (var i = 0; i < n; ++i) { // Get the position of each sorted key.
index[sortedKeys[i]] = i;
}
var sorted = new Array(n);
for (var i = 0; i < n; ++i) { // Look up each object key in the index.
sorted[index[objects[i][keyName]]] = objects[i];
}
return sorted;
}
var objects = [{id: 'Tweety', animal: 'bird'},
{id: 'Mickey', animal: 'mouse'},
{id: 'Sylvester', animal: 'cat'}],
sortedIds = ['Tweety', 'Mickey', 'Sylvester'];
var sortedObjects = objectsSortedBy(objects, 'id', sortedIds);
// Check the result.
for (var i = 0; i < sortedObjects.length; ++i) {
document.write('id: '+sortedObjects[i].id+', animal: '+sortedObjects[i].animal+'<br />');
}
To my understanding, sorting is not necessary; at least in your example, the desired resulting array can be generated in linear time as follows.
var Result;
for ( var i = 0; i < Input.length; i++ )
{
Result[i] = Input[Order[i]-1];
}
Here Result is the desired output, Input is your first array and Order the array containing the desired positions.
var objArray = [{id:1},{id:2},{id:3}];
var sortOrder = [2,3,1];
var newObjArray = [];
for (i in sortOrder) {
newObjArray.push(objArray[(sortOrder[i]) - 1])
};
Why not just create new array and push the value from second array in?? Correct me if i wrong
array1 = [];
array2 = [2,3,1];
for ( var i = 0; i < array2 .length; i++ )
{
array1.push({
id : array2[i]
})
}

Categories