aggregated sum based on keys in javascript - javascript

I have an array of object that looks like this
var data = [];
data[0] = {'TrueDestination': 'EU.UK.London', 'EU.UK.London':5, 'EU.UK.Bath':4, 'EU.France.Lyon':1, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':4},
data[1] = {'TrueDestination': 'EU.UK.Bath', 'EU.UK.London':7, 'EU.UK.Bath':1, 'EU.France.Lyon':8, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':1},
data[2] = {'TrueDestination': 'EU.France.Paris', 'EU.UK.London':2, 'EU.UK.Bath':2, 'EU.France.Lyon':2, 'EU.France.Paris':6, 'Asia.Japan.Tokyo':3},
data[3] = {'TrueDestination': 'EU.France.Lyon', 'EU.UK.London':9, 'EU.UK.Bath':0, 'EU.France.Lyon':1, 'EU.France.Paris':0, 'Asia.Japan.Tokyo':2},
data[4] = {'TrueDestination': 'EU.France.Lyon', 'EU.UK.London':2, 'EU.UK.Bath':4, 'EU.France.Lyon':3, 'EU.France.Paris':7, 'Asia.Japan.Tokyo':7},
I would like to
apply a function to the keys of my objects in my data so I can remove dot separated strings. So for example remove London or UK.London from EU.UK.London but not UK from UK.London or from EU.UK.London. (Added after a comment by T.J. Crowder below: to avoid confusion, you remove going backwards)
Then, for each object to take the aggregated sum grouped by the key
For instance if I strip the city, the last bit in the key strings, i want to end up with an array
var data = [];
data[0] = {'TrueDestination': 'EU.UK', 'EU.UK':9, 'EU.France':1, 'Asia.Japan':4},
data[1] = {'TrueDestination': 'EU.UK', 'EU.UK':8, 'EU.France':8, 'Asia.Japan':1},
data[2] = {'TrueDestination': 'EU.France', 'EU.UK':4, 'EU.France':8, 'Asia.Japan':3},
data[3] = {'TrueDestination': 'EU.France', 'EU.UK':9, 'EU.France':1, 'Asia.Japan':2},
data[4] = {'TrueDestination': 'EU.France', 'EU.UK':6, 'EU.France':10, 'Asia.Japan':7},
I have written this to strip the keys
function stripper(d, k){
// k controls how many times you want to strip the string
for (i=0; i<k; ++i){
if (d.lastIndexOf('.') > 0){
d = d.substring(0, d.lastIndexOf('.'))
}
}
return d
}
but my function to work on the keys is a real embarrassment. (and it doesnt work!) Anyways, this is where I am so far
stripLevel = 1
columnNames = data.columns.map(d => stripper(d, stripLevel))
for (j=0; j<columnNames.length; ++j){
cname = columnNames[j];
for (i=0; i<data.length; ++i) {
var _obj = {}
obj = data[i]
_keys = Object.keys(obj)
total = 0
for (k = 0; k < _keys.length; ++k) {
cur = _keys[k]
if ((cname != 'model_class') && (stripper(cur, stripLevel) === cname)) {
total += parseFloat(obj[cur])
}
_objTemp = {[stripper(cur, stripLevel)]: total}
Object.assign(_obj, _objTemp)
total = 0
}
}
}
Any help greatly appreciated

You could create new object and add the values of the same key.
It works with the entries of the object and the destructured key/value pair k/v and a function for getting the first parts of the dotted strings and a check of the key.
If the key k is equal to TrueDestination, then it takes the unchanged key and assigns the changed value to it. in all other cases, it takes the value of the property with the new key or zero, adds the value and assign the sum to the property.
Finally the object is returned.
var data = [{ TrueDestination: 'EU.UK.London', 'EU.UK.London': 5, 'EU.UK.Bath': 4, 'EU.France.Lyon': 1, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 4 }, { TrueDestination: 'EU.UK.Bath', 'EU.UK.London': 7, 'EU.UK.Bath': 1, 'EU.France.Lyon': 8, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 1 }, { TrueDestination: 'EU.France.Paris', 'EU.UK.London': 2, 'EU.UK.Bath': 2, 'EU.France.Lyon': 2, 'EU.France.Paris': 6, 'Asia.Japan.Tokyo': 3 }, { TrueDestination: 'EU.France.Lyon', 'EU.UK.London': 9, 'EU.UK.Bath': 0, 'EU.France.Lyon': 1, 'EU.France.Paris': 0, 'Asia.Japan.Tokyo': 2 }, { TrueDestination: 'EU.France.Lyon', 'EU.UK.London': 2, 'EU.UK.Bath': 4, 'EU.France.Lyon': 3, 'EU.France.Paris': 7, 'Asia.Japan.Tokyo': 7 }],
result = data.map(o => Object.entries(o).reduce((o, [k, v]) => {
const firsts = k => k.split('.').slice(0, -1).join('.');
if (k === 'TrueDestination') {
o[k] = firsts(v);
} else {
k = firsts(k);
o[k] = (o[k] || 0) + v;
}
return o;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Count the number of repeated letters from the array of each string

i have an array of strings with duplicated letters , Now i want to count the number of duplicated letters from each string and need to create a separate object for each string.
The given array :
let ArrOfStrs = ["aaabbbccc", "dddeeefff", "ggghhhiii", "jkl"]
what i have tried :
var obj={}
var repeats=[];
for(let i=0; i< ArrOfStrs.length; i++) {
for(let x = 0; x < ArrOfStrs[i].length; x++) {
var l = ArrOfStrs[i].charAt(x);
obj[l] = (!obj.hasOwnProperty(l) ? 1 : obj[l] + 1);
}
}
repeats.push(obj);
console.log(repeats);
Actual output :
{ a: 3, b: 3, c: 3, d: 3, e: 3, f: 3, g: 3, h: 3, i: 3, j: 1, k: 1, l: 1 }
Expected output :
[{a:3,b:3,c:3}, {d:3,e:3,f:3},{g:3,h:3,i:3},{j:1,k:1,l:1}]
Could some one help for better approach to achieve this.
Thanks in advance.
2 mistakes :
You are keeping a common object obj and making changes to it. Infact obj will be different for every string.
You are not pushing obj into your result array for every iteration. You are doing it in the end, hence you have only one item in your array.
Making minimal changes, your code can be fixed:
let ArrOfStrs = ["aaabbbccc", "dddeeefff", "ggghhhiii", "jkl"]
var repeats=[];
for(let i=0; i< ArrOfStrs.length; i++) {
var obj={}
for(let x = 0; x < ArrOfStrs[i].length; x++) {
var l = ArrOfStrs[i].charAt(x);
obj[l] = (!obj.hasOwnProperty(l) ? 1 : obj[l] + 1);
}
repeats.push(obj);
}
console.log(repeats);
Array.prototype.map to create a new array from an existing one
Array.prototype.reduce to convert an array to a different type (Object)
Spread syntax ... to convert String to Array
const arrOfStrs = ["aaabbbccc", "dddeeefff", "ggghhhiii", "jkl"];
const counted = arrOfStrs.map(str => [...str].reduce((o, v) => {
o[v] ??= 0 // set default count to 0 (if not exists)
o[v]++ // increment count
return o;
}, {}));
console.log(counted);
Additional read:
Nullish coalescent operator ??
Variant:
const arrOfStrs = ["aaabbbccc", "dddeeefff", "ggghhhiii", "jkl"];
const counted = arrOfStrs.map(s => [...s].reduce((o, v) => (o[v] ??= 0, o[v]++, o), {}));
console.log(counted);

Javascript: Split an array according to a pattern: items 1, 5, 10, then 2, 6, 11, then 3, 7, 12

I am trying to split an array which has a repeating pattern of elements 1, 2, 3, and 4. I want to turn my array [1,2,3,4,5,6,7,8,9,10] into four arrays: [1,5,10], [2,6,11], [3,7,12], and [4,8,13]. I tried using multiples, but the result creates the new arrays in a wrong order. Here is my attempt:
var upload_names_and_ids = [
"Certificat de salaire", //first line is the upload's visible title
"certificat-de-salaire", //second line is the upload's id
"no-info-circle", //third line is the info-circle class
"", //fourth line is the info-circle text
"Allocations Familiales",
"alloc-familiales",
"no-info-circle",
"",
"Courrier Impot (déclaration précédente)",
"courrier-impot",
"info-circle right",
""
];
//Seperate our first array into 4
var upload_names = [];
var upload_ids = [];
var upload_info_circle_class = [];
var upload_info_circle_content = [];
for (var i=0; i<upload_names_and_ids.length; i++){
if (i%4==0) {
upload_info_circle_content.push(upload_names_and_ids[i]);
} else if (i%3==0) {
upload_info_circle_class.push(upload_names_and_ids[i]);
} else if (i%2==0) {
upload_names.push(upload_names_and_ids[i]);
} else {
upload_ids.push(upload_names_and_ids[i]);
}
}
Any help is much appreciated, thank you!
You could take a remainder with index and wanted length.
const
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
length = 4,
result = array.reduce(
(r, v, i) => (r[i % length].push(v), r),
Array.from({ length }, _ => [])
);
console.log(result);
If you like to use predeclared array directly, you could replace this line
Array.from({ length }, _ => [])
with
[upload_names, upload_ids, upload_info_circle_class, upload_info_circle_content]
where the accumulator of Array#reduce keeps the object references.
It's not i%3==0 (which matches 0, 3, 6, …) but i%4==1 (to match 1, 5, 10, …). Same for i%2==0.
I would add a helper sliceN that takes an array and a positive integer. Then returns an array of arrays where the inner arrays are of length n.
sliceN([1,2,3,4,5,6,7,8,9], 3) //=> [[1,2,3], [4,5,6], [7,8,9]]
sliceN([1,2,3,4,5,6], 2) //=> [[1,2], [3,4], [5,6]]
Then also add a helper transpose that transposes a matrix.
transpose([[1,2,3], [4,5,6], [7,8,9]]) //=> [[1,4,7], [2,5,8], [3,6,9]]
transpose([[1,2], [3,4], [5,6]]) //=> [[1,3,5], [2,4,6]]
With these two helpers you can create the wanted result with ease.
const upload_names_and_ids = [
"Certificat de salaire", //first line is the upload's visible title
"certificat-de-salaire", //second line is the upload's id
"no-info-circle", //third line is the info-circle class
"", //fourth line is the info-circle text
"Allocations Familiales",
"alloc-familiales",
"no-info-circle",
"",
"Courrier Impot (déclaration précédente)",
"courrier-impot",
"info-circle right",
""
];
const [
upload_names,
upload_ids,
upload_info_circle_class,
upload_info_circle_content,
] = transpose(sliceN(upload_names_and_ids, 4));
console.log(upload_names);
console.log(upload_ids);
console.log(upload_info_circle_class);
console.log(upload_info_circle_content);
function sliceN(array, n) {
const slices = [];
for (let i = 0; i < array.length; i += n) {
slices.push(array.slice(i, i + n));
}
return slices;
}
function transpose(rows) {
if (rows.length == 0) return [];
const columns = rows[0].map(cell => Array.of(cell));
for (let iRow = 1; iRow < rows.length; iRow += 1) {
for (let iCol = 0; iCol < columns.length; iCol += 1) {
columns[iCol].push(rows[iRow][iCol]);
}
}
return columns;
}
If you are already use a library with helper functions chances are that one or both of these data transforming methods are present. sliceN can often be found as something with split, slice or chunk in the name. transpose is very specific and if present will probably be present under the same name.
As an example Ramda offers both these methods.
R.transpose(R.splitEvery(4, upload_names_and_ids))

Take highest property value and return it in an array in Javascript

I want to loop through this object and return the keys with the highest property values into an array.
Object {clear-spring: 3, deep-autumn: 2, warm-spring: 1, light-summer: 2, light-spring: 2, clear-summer: 3}
In this case, I want an array like this:
["clear-summer", "clear-spring"]
Is there an efficient way to do this with jQuery or pure javascript?
You simply need to iterate over your item once, keeping track of what ever the largest set is that you've found so far.
var a = {'clear-spring': 3, 'deep-autumn': 2, 'warm-spring': 1, 'light-summer': 2, 'light-spring': 2, 'clear-summer': 3};
var max = {
val: Number.NEGATIVE_INFINITY,
keys: []
}
for (var prop in a) {
if (a.hasOwnProperty(prop)) {
var n = a[prop];
if (n >= max.val) {
if (n > max.val) {
max.keys = [];
}
max.val = n;
max.keys.push(prop);
}
}
}
You may use for.. in to loop through the object
var object = {clear-spring: 3, deep-autumn: 2, warm-spring: 1, light-summer: 2, light-spring: 2, clear-summer: 3};
// Iterates over the oject
for (var key in object) {
if(object.hasOwnProperty(key)) {
// Key === 'clear-spring' (sample)
// object[key] === 3 (sample)
// do whatever you want
}
}
var o = {'clear-spring': 3, 'deep-autumn': 2, 'warm-spring': 1, 'light-summer': 2, 'light-spring': 2, 'clear-summer': 3};
var max = 0, result = [];
// find max:
for(var k in o) { if (o[k] > max) max = o[k] }
// find keys matching the max:
for(var k in o) { if (o[k] === max) result.push(k) }
// log result
console.log(result);
Not sure if most efficient, but first find the max value, then go back and pull out all the ones that match max value.
var obj = {'clear-spring': 3, 'deep-autumn': 2, 'warm-spring': 1, 'light-summer': 2, 'light-spring': 2, 'clear-summer': 3};
var ary = [];
var max = Number.NEGATIVE_INFINITY;
for (var prop in obj) {
if (obj[prop] > max) {
max = obj[prop];
}
}
for (var prop in obj) {
if (obj[prop] === max) {
ary.push(prop);
}
}

Javascript, repeating an object key N-times, being N its value

I was wondering how to do this in the more cleaner and optimal way:
I have an Object with the following structure:
{
"125": 2,
"439": 3,
"560": 1,
"999": 2,
...
}
I want to create a flat array repeating every key, the number of times indicated by its value. And bonus points for converting keys (strings) to integers. In this example, the resulting array should be:
[ 125, 125, 439, 439, 439, 560, 999, 999 ]
I've tried several ways but they all look over-engineered. For sure there is an easier way.
This is what I've got with underscore (and it returns an Array of strings, nor integers):
_.compact(_.flatten(_.map(files, function(num, id) {
return new Array(num+1).join('$'+id).split('$')
})))
I know there are plenty of ways to accomplish this. I just only want a clean and quick way. Being a Ruby developer it could be as easy as:
> files = {"125" => 2, "439" => 3, "560" => 1, "999" => 2}
=> {"125"=>2, "439"=>3, "560"=>1, "999"=>2}
> files.map {|key, value| [key.to_i] * value}.flatten
=> [125, 125, 439, 439, 439, 560, 999, 999]
Thanks in advance.
Try this:
var obj = {
"125": 2,
"439": 3,
"560": 1,
"999": 2
}
var arr = [];
for (prop in obj) {
for (var i = 0; i < obj[prop]; i++)
arr.push(parseInt(prop));
}
console.log(arr)
I know this is plain JavaScript but seems cleaner to me than the code you posted:
var dict = {
"125": 2,
"439": 3,
"560": 1,
"999": 2
}
var result = [];
for(key in dict)
for(i = 0; i < dict[key]; i++)
result.push(key * 1);
alert(result);
Hmm... not sure if I got at, but maybe something like this:
var myObj = {
"125": 2,
"439": 3,
"560": 1,
"999": 2
},
myArray = [];
for(k in myObj){
for(i = 0; i < myObj[k]; i++){
myArray.push(k);
}
}
console.log(myArray)
The problem with the other answers above is that the for..in language construct in javascript is going to involve all keys from the objects prototype chain. In this case, we should check and add only the correct keys.
var obj= {
"125": 2,
"439": 3,
"560": 1,
"999": 2
}
var arr=[];
for (var item in map) {
//important check!
if (map.hasOwnProperty(item)) {
arr.push(item);
}
}
Also see: http://www.yuiblog.com/blog/2006/09/26/for-in-intrigue/
Whether any of these approaches is cleaner is quite subjective:
// some helper function for creating an array with repeated values
function repeat(val, times) {
var arr = [];
for(var i = 0; i < times; i = arr.push(val));
return arr;
}
function convert(obj) {
var result = [], key;
for(key in obj) {
result = result.concat(repeat(+key, obj[key]));
}
return result;
}
Or a more functional approach:
Object.keys(obj).reduce(function(result, key) {
return result.concat(repeat(+key, obj[key]));
}, []);
// with underscore.js
_.reduce(_.keys(obj), function(result, key) {
return result.concat(repeat(+key, obj[key]));
}, []);
A helper function:
function flatten(obj){
//static Array method: create array (a elements, value b)
Array.aXb = Array.aXb || function(a,b){
b = b || 0;
return String(this(a)).split(',').map(function(){return b;});
}
//obj2array
var arr = [];
for (var k in obj)
if (+obj[k]) arr = arr.concat(Array.aXb(+obj[k],k));
return arr;
}
var obj= {"125": 2,"439": 3,
"560": 1,"999": 2 },
flatten(obj); //=> [125,125,439,439,439,560,999,999]

Convert simple array into two-dimensional array (matrix)

Imagine I have an array:
A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
And I want it to convert into 2-dimensional array (matrix of N x M), for instance like this:
A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));
Note, that rows and columns of the matrix is changeable.
Something like this?
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
Usage:
var matrix = listToMatrix([1, 2, 3, 4, 4, 5, 6, 7, 8, 9], 3);
// result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
You can use the Array.prototype.reduce function to do this in one line.
ECMAScript 6 style:
myArr.reduce((rows, key, index) => (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
myArr.reduce(function (rows, key, index) {
return (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
You can change the 3 to whatever you want the number of columns to be, or better yet, put it in a reusable function:
ECMAScript 6 style:
const toMatrix = (arr, width) =>
arr.reduce((rows, key, index) => (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
function toMatrix(arr, width) {
return arr.reduce(function (rows, key, index) {
return (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
}
This code is generic no need to worry about size and array, works universally
function TwoDimensional(arr, size)
{
var res = [];
for(var i=0;i < arr.length;i = i+size)
res.push(arr.slice(i,i+size));
return res;
}
Defining empty array.
Iterate according to the size so we will get specified chunk.That's why I am incrementing i with size, because size can be 2,3,4,5,6......
Here, first I am slicing from i to (i+size) and then I am pushing it to empty array res.
Return the two-dimensional array.
The cleanest way I could come up with when stumbling across this myself was the following:
const arrayToMatrix = (array, columns) => Array(Math.ceil(array.length / columns)).fill('').reduce((acc, cur, index) => {
return [...acc, [...array].splice(index * columns, columns)]
}, [])
where usage would be something like
const things = [
'item 1', 'item 2',
'item 1', 'item 2',
'item 1', 'item 2'
]
const result = arrayToMatrix(things, 2)
where result ends up being
[
['item 1', 'item 2'],
['item 1', 'item 2'],
['item 1', 'item 2']
]
How about something like:
var matrixify = function(arr, rows, cols) {
var matrix = [];
if (rows * cols === arr.length) {
for(var i = 0; i < arr.length; i+= cols) {
matrix.push(arr.slice(i, cols + i));
}
}
return matrix;
};
var a = [0, 1, 2, 3, 4, 5, 6, 7];
matrixify(a, 2, 4);
http://jsfiddle.net/andrewwhitaker/ERAUs/
Simply use two for loops:
var rowNum = 3;
var colNum = 3;
var k = 0;
var dest = new Array(rowNum);
for (i=0; i<rowNum; ++i) {
var tmp = new Array(colNum);
for (j=0; j<colNum; ++j) {
tmp[j] = src[k];
k++;
}
dest[i] = tmp;
}
function matrixify( source, count )
{
var matrixified = [];
var tmp;
// iterate through the source array
for( var i = 0; i < source.length; i++ )
{
// use modulous to make sure you have the correct length.
if( i % count == 0 )
{
// if tmp exists, push it to the return array
if( tmp && tmp.length ) matrixified.push(tmp);
// reset the temporary array
tmp = [];
}
// add the current source value to the temp array.
tmp.push(source[i])
}
// return the result
return matrixified;
}
If you want to actually replace an array's internal values, I believe you can call the following:
source.splice(0, source.length, matrixify(source,3));
This a simple way to convert an array to a two-dimensional array.
function twoDarray(arr, totalPerArray) {
let i = 0;
let twoDimension = []; // Store the generated two D array
let tempArr = [...arr]; // Avoid modifying original array
while (i < arr.length) {
let subArray = []; // Store 2D subArray
for (var j = 0; j < totalPerArray; j++) {
if (tempArr.length) subArray.push(tempArr.shift());
}
twoDimension[twoDimension.length] = subArray;
i += totalPerArray;
}
return twoDimension;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
twoDarray(arr, 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
function changeDimension(arr, size) {
var arrLen = arr.length;
var newArr = [];
var count=0;
var tempArr = [];
for(var i=0; i<arrLen; i++) {
count++;
tempArr.push(arr[i]);
if (count == size || i == arrLen-1) {
newArr.push(tempArr);
tempArr = [];
count = 0;
}
}
return newArr;
}
changeDimension([0, 1, 2, 3, 4, 5], 4);
function matrixify(array, n, m) {
var result = [];
for (var i = 0; i < n; i++) {
result[i] = array.splice(0, m);
}
return result;
}
a = matrixify(a, 3, 3);
function chunkArrToMultiDimArr(arr, size) {
var newArray = [];
while(arr.length > 0)
{
newArray.push(arr.slice(0, size));
arr = arr.slice(size);
}
return newArray;
}
//example - call function
chunkArrToMultiDimArr(["a", "b", "c", "d"], 2);
you can use push and slice like this
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array) ;
console.log(newarray[0]) ;
output will be
[[1, 2, 3, 4, 5, 6, 7, 8, 9]]
if you want divide array into 3 array
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array.slice(0,2)) ;
newarray[1].push(array.slice(3,5)) ;
newarray[2].push(array.slice(6,8)) ;
instead of three lines you can use splice
while(array.length) newarray.push(array.splice(0,3));
const x: any[] = ['abc', 'def', '532', '4ad', 'qwe', 'hf', 'fjgfj'];
// number of columns
const COL = 3;
const matrix = array.reduce((matrix, item, index) => {
if (index % COL === 0) {
matrix.push([]);
}
matrix[matrix.length - 1].push(item);
return matrix;
}, [])
console.log(matrix);
Using the Array grouping proposal (currently stage 3), you can now also do something like the following:
function chunkArray(array, perChunk) {
return Object.values(array.group((_, i) => i / perChunk | 0));
}
See also the MDN documentation for Array.prototype.group().
Simplest way with ES6 using Array.from()
const matrixify = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size));
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ;
console.log(matrixify(list, 3));
Another stab at it,
Creating an empty matrix (Array of row arrays)
Iterating arr and assigning to matching rows
function arrayToMatrix(arr, wantedRows) {
// create a empty matrix (wantedRows Array of Arrays]
// with arr in scope
return new Array(wantedRows).fill(arr)
// replace with the next row from arr
.map(() => arr.splice(0, wantedRows))
}
// Initialize arr
arr = new Array(16).fill(0).map((val, i) => i)
// call!!
console.log(arrayToMatrix(arr, 4));
// Trying to make it nice
const arrToMat = (arr, wantedRows) => new Array(wantedRows).fill(arr)
.map(() => arr.splice(0, wantedRows))
(like in: this one)
(and: this one from other thread)
MatArray Class?
Extending an Array to add to a prototype, seems useful, it does need some features to complement the Array methods, maybe there is a case for a kind of MatArray Class? also for multidimensional mats and flattening them, maybe, maybe not..
1D Array convert 2D array via rows number:
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
console.log(twoDimensional([1,2,3,4,5,6,7,8,9,10,11,12,13,14], 3))
Short answer use:
const gridArray=(a,b)=>{const d=[];return a.forEach((e,f)=>{const
h=Math.floor(f/b);d[h]=d[h]||[],d[h][f%b]=a[f]}),d};
Where:
a: is the array
b: is the number of columns
An awesome repository here .
api : masfufa.js
sample : masfufa.html
According to that sample , the following snippet resolve the issue :
jsdk.getAPI('my');
var A=[1, 2, 3, 4, 5, 6, 7, 8, 9];
var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'});
then :
MX.get[0][0] // -> 1 (first)
MX.get[2][2] // ->9 (last)

Categories

Resources