How to merge two 2 dimensional arrays with Jquery - javascript

I want to merge the oldData and newData. Need to show output by sorting date as ascending. If data is available in both, add as [date , oldValue , New value]. If data available in newData only then create like [ '2018-03-30', null, 5 ]
var oldData = [ [ '2018-04-01', 10 ], [ '2018-04-02', 20 ], [ '2018-04-03', 30 ] ];
var newData = [ [ '2018-03-30', 5 ], [ '2018-03-31', 6 ], [ '2018-04-01', 22 ] ];
The desired output would be:
[ [ '2018-03-30', null, 5 ], [ '2018-03-31', null, 6 ], [ '2018-04-01', 10, 22 ] , [ '2018-04-02', 20, null ] , [ '2018-04-03', 30, null ] ];
Please help me achieve this in jquery / java-script.

I'd do something like that:
let output = [];
oldData.map(e => output.push([new String(e[0]), e[1], null]));
for(const elem of newData) {
output.map(e => {
if(e[0] === elem[0]) {
e[2] = elem[1];
continue;
}
})
output.push([new String(elem[0]), null, elem[1]]);
}
You create new array with the values from the oldData, in a desired structure (I user new String() to make sure I don't just copy a reference - remove if not needed).
Then you loop over the elements of newData to see if ouptut already has an elem. with that date.
If so, you change the null inside it to a number from coresponding element.
If not, you just push a new one with given date, null and a number.
Remeber that this will work properly only when the items are unique!

Related

how to get the first item in nested, filtered array in javascirpt

I've got an array:
const aContracts = [[ '0x8ae127d224094cb1b27e1b28a472e588cbcc7620', 0 ],
[ '0xcbf4ab00b6aa19b4d5d29c7c3508b393a1c01fe3', 0 ],
[ '0x03cd191f589d12b0582a99808cf19851e468e6b5', 0 ],
[ '0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a', 1 ]]
And I'm trying to filter using the second item in each sub-array. So I used:
const aGoodContracts = aContracts.filter(contracts => contracts[1]===1);
And I get:
[["0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a", 1]]
However, I want [EDIT I want an array of all the "good" contracts]:
"0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a"
So I tried a solution I found here:
const aGoodContracts = aContracts.map(k => k.filter(contracts => contracts[1]===1));
But I get:
[[], [], [], []]
What am I missing?
Just map() your result to pick out the first element in the array. This will leave you with an array, and if you just want the first value (like your expected output) grab the zero index element.
const aContracts = [[ '0x8ae127d224094cb1b27e1b28a472e588cbcc7620', 0 ],
[ '0xcbf4ab00b6aa19b4d5d29c7c3508b393a1c01fe3', 0 ],
[ '0x03cd191f589d12b0582a99808cf19851e468e6b5', 0 ],
[ '0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a', 1 ]]
const aGoodContracts = aContracts.filter(contracts => contracts[1]===1).map(c => c[0]);
console.log(aGoodContracts);
console.log(aGoodContracts[0]);
You can try this
const aContracts = [[ '0x8ae127d224094cb1b27e1b28a472e588cbcc7620', 0 ],
[ '0xcbf4ab00b6aa19b4d5d29c7c3508b393a1c01fe3', 0 ],
[ '0x03cd191f589d12b0582a99808cf19851e468e6b5', 0 ],
[ '0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a', 1 ]]
const aGoodContracts = aContracts.filter(contracts => contracts[1]===1)[0]
console.log(aGoodContracts[0])

Iterating through a matrix of irregular row lengths

I've got a matrix where rows don't necessarily have the same length:
The following are musical tokens in the format of solfege.
const notes = [
[ 'do5', 'mi5' ],
[ 'mi6', 'so6', 'ti6', 're7' ],
[ 'so7', 'ti7', 're8', 'fa8' ],
[ 'la3', 'do4', 'mi4' ],
[ 'fa2', 'la2' ],
[ 're2' ],
[ 'ti1', 're2', 'fa2' ]
];
I have a function that converts these tokens into equivalent alphabetic tokens (for example: fa2 would be converted to F2 using my function).
I would like to be able to iterate over this matrix, and return the transformed matrix, which should retain the same dimensions.
Thanks,
Nakul
Here's what you probably want:
const notes = [
[ 'do5', 'mi5' ],
[ 'mi6', 'so6', 'ti6', 're7' ],
[ 'so7', 'ti7', 're8', 'fa8' ],
[ 'la3', 'do4', 'mi4' ],
[ 'fa2', 'la2' ],
[ 're2' ],
[ 'ti1', 're2', 'fa2' ]
];
// replace this function with your own converter
function convert(note) {
return note.toUpperCase();
}
for (let i = 0; i < notes.length; i++) { // for each row
// map will iterate through the row, converting each note
notes[i] = notes[i].map(convert);
}
The part map(convert) is just a shorter form of map(note => convert(note)).
This is not very efficient, as map() will create a new array for each row, but in your case it's probably more important that the code is readable rather than performant, so that's fine.
You can use the new Array.prototype.flat() function, but, if you want wider support (.flat() is ignored by both Edge and IE), then I would use two for..of loops.
const arr = [
[ 'do5', 'mi5' ],
[ 'mi6', 'so6', 'ti6', 're7' ],
[ 'so7', 'ti7', 're8', 'fa8' ],
[ 'la3', 'do4', 'mi4' ],
[ 'fa2', 'la2' ],
[ 're2' ],
[ 'ti1', 're2', 'fa2' ]
];
// Modern JavaScript
for (const item of arr.flat()) {
console.log(item);
}
console.log('----');
// More widely supported JavaScript
for (const subarray of arr) {
for (const subitem of subarray) {
console.log(subitem);
}
}

Confusing about removing empty subarrays in JavaScript

I have an array with a size of 5 and in each element, I fill in with a corresponding subarray, like this:
let equalSums = new Array(5);
for (let i = 0; i < equalSums.length; i++) {
equalSums[i] = new Array(5);
}
console.log(equalSums);
/*
[ [ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ] ]
*/
And after malnipulating to find contigous subarray that equal to a give number (in this case it's 3), I push subarray with sum elements equal 3 to this equalSum array, and now it looks like this:
[ [ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ],
[ 1, 2 ],
[ 2, 1 ],
[ 3 ] ]
The problem is I want to remove all the empty subarrays, then I do the following:
let rs = equalSums.filter(e => e.every(x => x != ""));
console.log(rs);
/*
[ [ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ],
[ , , , , ],
[ 1, 2 ],
[ 2, 1 ],
[ 3 ] ]
/*
Still the same, it doesn't remove the empty subarrays.
But, I use some instead, it gives me the desired result:
let rs = equalSums.filter(e => e.some(x => x != ""));
console.log(rs);
/*
[ [ 1, 2 ], [ 2, 1 ], [ 3 ] ]
*/
Can anybody explain for me why every doesn't work and some does?
The sparse [,,,,] arrays you have there essentially have no elements, only spaces that are occupied by nothing.
So [,,,,,].every(x => x != '') asks, "Are all of this array's elements unequal to ""?" And the answer is Yes. It has no elements, so all of the elements it has (none) are unequal to "".
[,,,,].some(x => x != "") asks, "Does this array have any elements that are unequal to ""?" And the answer is No. It has no elements, so it doesn't have any that are unequal to "".
You haven't really explained why you're using all these sparse arrays, and I suspect you might be going about whatever you're trying to do in the wrong way, but at least this explains what you are seeing with every and some.
Please note that [,,,,] is considered to be an empty array and will behave the same way as [] when using every and some even tho it says it has a length of 4.
more info on that
every and some return different values if you call them on an empty array.
[].every(x => x)
true
[].some(x => x)
false
Your code seem to rely on this behavior to filter out empty arrays, your check x != "" is not what doing the filtering.

adding copy of array to another array

I am trying to add a copy of an array to another array with array.slice(), but when I update the original, it updates the copy that I added. How can I add a copy that isn't altered when the original is altered?
I've tried using result.unshift[...curRow], and result.unshift(curRow.slice()) when I add
function game(n) {
var result = [];
let row1=[[1, 2]];
for (var i=1;i<n;i++){
var cur = row1[i];
var prev = row1[i - 1];
row1.push([prev[0] + 1, prev[1] + 1]);
}
result.push(row1.slice());
let curRow = row1.slice();
for (var i=1;i<n;i++){
for (var j = 0; j<curRow.length ;j++){
curRow[j][1]++;
}
result.unshift(curRow.slice());
console.log('curRow =',curRow);
console.log('result = ', result)
}
console.log('result = ', result)
return result
}
game(3);
This is my current output:
'result ='[ [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ] ] ]
'result = '[ [ [ 1, 3 ], [ 2, 4 ], [ 3, 5 ] ], [ [ 1, 3 ], [ 2, 4 ], [ 3, 5 ] ] ]
'result = '[ [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ], [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ], [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ] ]
I want the result array to contain each iteration of the curRow array, instead of just having copies of the latest one.
In JavaScript, objects/arrays, also known as non-primitive types, are given a reference, rather than value. Therefore, this particular reference points to the object's location in the memory. That variable you are working with has a 'reference' rather than containing an actual 'value'. This is why it is mutated when you use it on the game() function.
To work with that, you should create a shallow copy of that array, before making any manipulation/mutation to it.
const copy = originalArray.map(element => ({...element}));
Now, all changes to the copy array will not be applied to originalArray.
Because in Javascript Arrays are handled by reference, when you reasign an array to a new variable, the new variable only holds a reference to the original array. Any alteration on the original array will be reflected in any of its instances/references (beucause they are essentially the same object).
Since the ES6 version of the standard we have Array.from() to perform copies or duplicates of the contents of an Array.
It's my favorite way to go, is fast, safe and readable.
The Array.from() method creates a new, shallow-copied Array instance from an array-like or iterable object. Extended documentation here
Check the example :
let a = [1,2,3,4,5];
let b = Array.from(a);
// modify first array to test
a[0] = 666;
// output second array to check
console.log(b)
// [1,2,3,4,5] OK!
you can use this concept:
firstArray=firstArray.concat(...secondArray);

How to remove comma from my array value?

hi pretty new to javascript.I am pretty confused in spliting my array value
console.log(arr)//[ [ [ 10, 0 ] ], [ [ 8, 0 ] ], [ [ 8, 0 ] ], [ [ 5, 2 ] ] ]
var line = "";
arr.forEach(e => {
e.forEach(f => line += "[" + f.join(",") + "],");
});
console.log(line);//[10,0],[8,0],[8,0],[5,2],
But i want my ouptput like this to do matrix addition
console.log(line);//[[10,0],[8,0],[8,0],[5,2]]
You can use map() for this.
var arr = [ [ [ 10, 0 ] ], [ [ 8, 0 ] ], [ [ 8, 0 ] ], [ [ 5, 2 ] ] ];
var result = arr.map(function(a) {
return a[0];
});
console.log(result)
You could do this by changing where the join happens and pre/app-ending some square brackets, e.g.
var line = arr.map(e => e.map(f => f.join(",")));
console.log('[' + line.join('],[') + ']');
// [10,0],[8,0],[8,0],[5,2]
I do have to ask though, why are you getting back a set of arrays each with a single value? Is it possible to avoid getting a dataset like that in the first place? You could avoid the double map/foreach that way.
For instance if you had one level less nesting in your source array the map line would become a little simpler
var arr = [ [ 10, 0 ], [ 8, 0 ], [ 8, 0 ], [ 5, 2 ] ];
var line = arr.map(f => f.join(","));
console.log('[' + line.join('],[') + ']');
This is of course if you want to specifically output the string for the array matrix, if you just wanted a flatter version of your original array then you could do:
var newList = arr.map(f => f[0]);
// [ [ 10, 0 ], [ 8, 0 ], [ 8, 0 ], [ 5, 2 ] ]

Categories

Resources