I have a 2D array of row,through which i want get the column coordinates/information just like i got for the row(rowArr2D)
So,in my Column(colArr2D) i'm just getting all 4th position values in the array since i passed have oRowCount in the function
my goal is to get all columns respectively.
Example:
Row:[ [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ], [ 0, 1, 2, 3, 4, 5, 6 ] ]
Columns: [[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]]
mockTable = { // mocking the portions of my code
GetRowsCount : () => 4,
GetRow: (x) => ({
GetCellsCount : () => 7,
GetCell : (x) => x
})
}
CTable_prototype_GetTableMapping = function(currentTable)
{
//get row information
let oRowCount = currentTable.GetRowsCount();
const rowArr2D = Array(oRowCount);
for (let i = 0; i < oRowCount; i++) {
//get cell information and cell count
let oRow = currentTable.GetRow(i);
let oCellCount = oRow.GetCellsCount();
rowArr2D[i] = Array(oCellCount);
for (let j = 0; j < oCellCount; j++) {
//get cell content
let oCell = oRow.GetCell(j);
rowArr2D[i][j] = oCell;
}
}
// get column information
const colArr2D = (array, colCount) => {
const result = [];
array.forEach(e => {
result.push(e[colCount]);
});
console.log(result);
return result;
};
colArr2D(rowArr2D, oRowCount);
return rowArr2D
console.log(rowArr2D);
};
const theArray = CTable_prototype_GetTableMapping(mockTable);
console.log("full 2D array", theArray)
Give this a try
const colArr2D = (array) =>
array[0].map((a, i) =>
array.map(b => b[i])
);
const arr = [[1,2,3],[4,5,6],[7,8,9]];
console.log(colArr2D(arr))
I have got a function that produces an array that is made up of X amount of sub-arrays containing Y amount of objects. Both of these factors are passed to a function to produce an array that looks something like this:
[
[ { '0': 3 }, { '1': 4 }, { '2': 6 }, 'Estimate:': '0jvyt8a' ],
[ { '0': 4 }, { '1': 6 }, { '2': 3 }, 'Estimate:': 'mc973fs' ],
[ { '0': 4 }, { '1': 1 }, { '2': 3 }, 'Estimate:': 'vwsfh8k' ],
[ { '0': 4 }, { '1': 3 }, { '2': 5 }, 'Estimate:': 'n6xzge3' ],
[ { '0': 8 }, { '1': 7 }, { '2': 1 }, 'Estimate:': 'v0jn7bh' ]
]
My question is, is there a way I can convert this array from this structure. To a structure shown below:
[
[1,{1: "vwsfh8k"}, {2: "v0jn7bh"}]
[3,{1: "0jvyt8a"}, {2: "mc973fs"}, {3:"vwsfh8k"}, {4:"n6xzge3"}]
]
Basically, my aim is to take the original array generated by the script (see below) and pass it through another function to record how many times each number was present and what it's 'estimate' number was.
In this example, I just created random numbers between 0 and 10 so an option would be to iterate and count each value I guess but unfortunately, I can't do this because eventually I will be using 5-letter combinations instead of numbers but numbers were easiest to show for an example and proof of concept.
So, I guess, I need to get an array of each unique value and then look at each value up in the original array to find out what estimate IDs have it present. Unfortunately, I don't have even an idea of where, to begin with, this, so I was hoping you guys can help.
Code to generate random array:
// Making an empty array
const arr = [];
//Generating the estimate IDs and placing them all in their own object in their own array.
function estimateGen(length, nodes) {
for (var i = 0; i < length; i++) {
const estimate = [];
let estimateVal = Math.random().toString(36).replace('0.','').slice(0,7);
estimate[`Estimate:`] = estimateVal;
arr.push(estimate);
nodeGen(estimate, nodes)
}
}
// Adding x amount of nodes between 1 and 10 into each estimate sub-array in their own objects.
function nodeGen(estimate, nodes) {
for (var i = 0; i < nodes; i++) {
const node = {};
let nodeID = Math.floor(Math.random() * 10) + 1;
node[i] = nodeID;
estimate.push(node);
}
}
// Calling the function and saying how many nodes per estimate we want.
estimateGen(5, 3);
console.log(arr);
If you have any suggestions on how to improve this code or as to why the estimate values in the sub-array are always last in the array that would be very helpful.
Thank you
--- EDIT ---
I have changed the code that generates the original array to produce a simpler array.
// Making an empty array
const arr = [];
//Generating the estimate IDs and placing them all in their own object in their own array.
function estimateGen(length, nodes) {
for (var i = 0; i < length; i++) {
const estimate = [];
let estimateVal = Math.random().toString(36).replace('0.','').slice(0,7);
estimate.push(estimateVal);
arr.push(estimate);
nodeGen(estimate, nodes)
}
}
// Adding x amount of nodes between 1 and 10 into each estimate sub array in their own objects.
function nodeGen(estimate, nodes) {
for (var i = 0; i < nodes; i++) {
let nodeID = Math.floor(Math.random() * 10) + 1;
estimate.push(nodeID);
}
}
// Calling the function and saying how many nodes per estimate we want.
estimateGen(5, 3);
console.log(arr);
From this code I now get the result:
[
[ 'p68xw8h', 5, 4, 6 ],
[ 'wn2yoee', 5, 4, 5 ],
[ '1w01tem', 9, 7, 4 ],
[ 'we3s53f', 8, 8, 8 ],
[ '5nrtp09', 3, 3, 8 ]
]
Would there be a way to count the number of times the values on the right appear and what 'estimate' ID at [0] it appears in?
Thank you.
First, let's redesign your input data and results to be a more useful format:
// input
[
{ nodes: [3, 4, 6], Estimate: '0jvyt8a' },
{ nodes: [4, 6, 3], Estimate: 'mc973fs' },
{ nodes: [4, 1, 3], Estimate: 'vwsfh8k' },
{ nodes: [4, 3, 5], Estimate: 'n6xzge3' },
{ nodes: [8, 7, 1], Estimate: 'v0jn7bh' }
];
// result
{
1: ["vwsfh8k", "v0jn7bh"],
3: ["0jvyt8a", "mc973fs", "vwsfh8k", "n6xzge3"],
...
]
Then the code would be:
const input = [
{ nodes: [3, 4, 6], Estimate: '0jvyt8a' },
{ nodes: [4, 6, 3], Estimate: 'mc973fs' },
{ nodes: [4, 1, 3], Estimate: 'vwsfh8k' },
{ nodes: [4, 3, 5], Estimate: 'n6xzge3' },
{ nodes: [8, 7, 1], Estimate: 'v0jn7bh' }
];
const result = {};
input.forEach(({
nodes,
Estimate: e
}) =>
nodes.forEach(n => {
if (!result[n]) {
result[n] = [];
}
result[n].push(e);
})
);
console.log(result);
You can create the data with:
// Making an empty array
const arr = [];
//Generating the estimate IDs and placing them all in their own object in their own array.
function estimateGen(length, nodes) {
for (var i = 0; i < length; i++) {
let estimateVal = Math.random().toString(36).replace('0.', '').slice(0, 7);
const estimate = {
Estimate: estimateVal,
nodes: []
}
arr.push(estimate);
nodeGen(estimate, nodes)
}
}
// Adding x amount of nodes between 1 and 10 into each estimate sub array in their own objects.
function nodeGen(estimate, nodes) {
for (var i = 0; i < nodes; i++) {
let nodeID = Math.floor(Math.random() * 10) + 1;
estimate.nodes.push(nodeID);
}
}
// Calling the function and saying how many nodes per estimate we want.
estimateGen(5, 3);
console.log(arr);
I've reformatted your array. The output is different, but you can still use it.
var arr = [
{ '0': 3 , '1': 4 , '2': 6 , 'Estimate:': '0jvyt8a' },
{ '0': 4 , '1': 6 , '2': 3 , 'Estimate:': 'mc973fs' },
{ '0': 4 , '1': 1 , '2': 3 , 'Estimate:': 'vwsfh8k' },
{ '0': 4 , '1': 3 , '2': 5 , 'Estimate:': 'n6xzge3' },
{ '0': 8 , '1': 7 , '2': 1 , 'Estimate:': 'v0jn7bh' }
];
var num = [1, 3, 4, 5, 6, 7, 8];
num = num.map(n =>
[n, ...(
arr.filter(a => [0, 1, 2].some(nm => a[nm] === n))
.map(v => v["Estimate:"])
)]);
console.log(num);
For getting a counting object you could take the values as key and estimates as key for the count of same values.
function estimateGen(length, nodes) {
var array = [];
for (var i = 0; i < length; i++) {
array.push([Math.random().toString(36).replace('0.','').slice(0,7), ...nodeGen(nodes)]);
}
return array;
}
function nodeGen(nodes) {
var result = [];
for (var i = 0; i < nodes; i++) {
result.push(Math.floor(Math.random() * 10) + 1);
}
return result;
}
function count(data) {
return data.reduce((r, [estimate, ...values]) => {
values.forEach(v => {
r[v] = r[v] || {};
r[v][estimate] = (r[v][estimate] || 0) + 1;
});
return r;
}, {});
}
var temp = estimateGen(5, 3);
console.log(temp);
console.log(count(temp));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'm consuming JSON data that has a bit of a weird structure for example:
{
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
I would like to create some JavaScript that would restructure this data to proper JSON structures so that the "Column" array values become the keys for the "DATA" array's values. So after a JS process is run the data resembles the following:
[
{"ID":7,"name":"Site-A","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1},
{"ID":15,"name":"Site-B","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1}
]
What are the JavaScript best practices for accomplishing the JSON restructuring? Could I accomplish this task using a JS framework like JQuery, Foundation JS, ect... ?
Using Underscore, it's a one-liner:
var formatted = _.map(orig.RESULT.DATA, _.partial(_.object, orig.RESULT.COLUMNS));
With plain javascript (less elegant but faster), it would be
var formatted = [],
data = orig.RESULT.DATA,
cols = orig.RESULT.COLUMNS,
l = cols.length;
for (var i=0; i<data.length; i++) {
var d = data[i],
o = {};
for (var j=0; j<l; j++)
o[cols[j]] = d[j];
formatted.push(o);
}
newjson is your new object, j is your json,
code is very fast as it caches the legth and don't uses push.
And as it's pure javascript it's faster than all the libraries.
var j={
"RESULT":{
"COLUMNS":[
"ID",
"name",
"ENABLED",
"perms",
"vcenabled",
"vcvalue",
"checkenabled",
"checkvalue",
"indxenabled",
"indxvalue"
],
"DATA":[
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
var newjson=[],d=j.RESULT.COLUMNS.length;
for(var a=0,b=j.RESULT.DATA.length;a<b;a++){
for(var c=0,tmpObj={};c<d;c++){
tmpObj[j.RESULT.COLUMNS[c]]=j.RESULT.DATA[a][c];
}
newjson[a]=tmpObj;
}
console.log(newjson);
based on Bergi's response u can also use the while-- loop.
var orig={
"RESULT":{
"COLUMNS":[
"ID",
"name",
"ENABLED",
"perms",
"vcenabled",
"vcvalue",
"checkenabled",
"checkvalue",
"indxenabled",
"indxvalue"
],
"DATA":[
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
var formatted = [],
data = orig.RESULT.DATA,
cols = orig.RESULT.COLUMNS,
l = cols.length,
f = data.length;
while (f--) {
var d = data[f],
o = {},
g = l;
while (g--) {
o[cols[g]] = d[g];
}
formatted[f] = o;
}
you can use underscore Array functions for this task
http://underscorejs.org/#arrays
uusing the object function would be helpful
http://underscorejs.org/#object
from the documentation :
_.object(list, [values])
Converts arrays into objects. Pass either a single list of [key, value] pairs, or a list of keys, and a list of values ..the example:
_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
=> {moe: 30, larry: 40, curly: 50}
here is the JSfiddle with the solution
http://jsfiddle.net/rayweb_on/kxR88/1/
and the code looks like this for this specific scenario.
var plain = {
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
},
formatted = [];
_.each(plain.RESULT.DATA, function(value) {
var tmp = {};
tmp = _.object(plain.RESULT.COLUMNS,value)
formatted.push(tmp);
});
console.log(formatted);
Try this using underscorejs.
var plain = {
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
, formatted = [];
_.each(plain.RESULT.DATA, function(value) {
var tmp = {};
_.each(value, function(parameter, pos) {
tmp[plain.RESULT.COLUMNS[pos]] = parameter;
});
formatted.push(tmp);
});
console.log(formatted);
http://jsfiddle.net/kxR88/
Actually, you could use a combination of Array#map for the array and Array#reduce for the objects with the new properties
var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
result = data.RESULT.DATA.map(function (a) {
return a.reduce(function (o, d, i) {
o[data.RESULT.COLUMNS[i]] = d;
return o;
}, {});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With ES6, you could use Object.assign with spread syntax ....
Object.assign adds properties to the given object and returns this object.
Spread syntax ... takes an array and insert the elements as parameters to the function.
var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
result = data.RESULT.DATA.map(a =>
Object.assign(...data.RESULT.COLUMNS.map((k, i) => ({ [k]: a[i] }))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using JQuery:
function jsonToObj(json){
return jQuery.parseJSON(JSON.stringify(json));
}
For example, after a GET request the server send a complex object
$.get("/Files/-2", function (rxData, status) {
var obj = jsonToObj(rxData);
console.log(obj);
});
Logged in console, can be explored through Chrome's Web Developer (F12), in my case looks like this:
image showing nested levels
By simple JS, your solution would look like this:
var yourObj = {
"RESULT": {
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
//Solution
var finalARR = [];
var colLength = yourObj.RESULT.COLUMNS.length;
var dataLength = yourObj.RESULT.DATA.length;
for (var i = 0; i < dataLength; i++) {
var finalJSON = {};
for (var j = 0; j < colLength; j++) {
finalJSON[yourObj.RESULT.COLUMNS[j]] = yourObj.RESULT.DATA[i][j];
}
finalARR[i] = finalJSON;
}
console.log(finalARR);