How to remove comma from my array value? - javascript

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 ] ]

Related

Compare 2 arrays and combine in Javascript

How can i compare and combine 2 arrays using array functions of javascript or using lodash?
I have this initial array of dates for last 30 days.
[
'2022-12-11', '2022-12-12', '2022-12-13',
'2022-12-14', '2022-12-15', '2022-12-16',
'2022-12-17', '2022-12-18', '2022-12-19',
'2022-12-20', '2022-12-21', '2022-12-22',
'2022-12-23', '2022-12-24', '2022-12-25',
'2022-12-26', '2022-12-27', '2022-12-28',
'2022-12-29', '2022-12-30', '2022-12-31',
'2023-01-01', '2023-01-02', '2023-01-03',
'2023-01-04', '2023-01-05', '2023-01-06',
'2023-01-07', '2023-01-08', '2023-01-09',
'2023-01-10', '2023-01-11'
]
Then this is the second with count value.
[ [ '2023-01-09', 1 ], [ '2023-01-10', 3 ] ]
Now i have this code that compare and combine these array manually
let testData = [];
let k = 0;
dayList.forEach(o => {
let is_match = 0;
let frags = [];
submitted.forEach(i => {
if(o == i[0]){
is_match = 1;
frags = i;
}
});
testData[k] = [
(is_match == 1) ? frags[0] : o,
(is_match == 1) ? frags[1] : 0
];
k++;
});
console.log(testData);
this will result to...
[
[ '2022-12-11', 0 ], [ '2022-12-12', 0 ],
[ '2022-12-13', 0 ], [ '2022-12-14', 0 ],
[ '2022-12-15', 0 ], [ '2022-12-16', 0 ],
[ '2022-12-17', 0 ], [ '2022-12-18', 0 ],
[ '2022-12-19', 0 ], [ '2022-12-20', 0 ],
[ '2022-12-21', 0 ], [ '2022-12-22', 0 ],
[ '2022-12-23', 0 ], [ '2022-12-24', 0 ],
[ '2022-12-25', 0 ], [ '2022-12-26', 0 ],
[ '2022-12-27', 0 ], [ '2022-12-28', 0 ],
[ '2022-12-29', 0 ], [ '2022-12-30', 0 ],
[ '2022-12-31', 0 ], [ '2023-01-01', 0 ],
[ '2023-01-02', 0 ], [ '2023-01-03', 0 ],
[ '2023-01-04', 0 ], [ '2023-01-05', 0 ],
[ '2023-01-06', 0 ], [ '2023-01-07', 0 ],
[ '2023-01-08', 0 ], [ '2023-01-09', 1 ],
[ '2023-01-10', 3 ], [ '2023-01-11', 0 ]
]
As you can see the date 2023-01-09 and 2023-01-10 have values then the rest has 0 values.
Which is what i expected, i'm just new in coding a pure javascript application, i just translated my PHP code to javascript.
Now is there a way that this code may be simplified using array functions of javascript or using lodash?
Here's an approach, we first create a map with the date as key and count as value and then use this map to generate the result
const dates=["2022-12-11","2022-12-12","2022-12-13","2022-12-14","2022-12-15","2022-12-16","2022-12-17","2022-12-18","2022-12-19","2022-12-20","2022-12-21","2022-12-22","2022-12-23","2022-12-24","2022-12-25","2022-12-26","2022-12-27","2022-12-28","2022-12-29","2022-12-30","2022-12-31","2023-01-01","2023-01-02","2023-01-03","2023-01-04","2023-01-05","2023-01-06","2023-01-07","2023-01-08","2023-01-09","2023-01-10","2023-01-11",];
const count=[["2023-01-09",1],["2023-01-10",3]];
const countMap = count.reduce((acc, [date, count]) => {
acc[date] = count;
return acc;
}, {});
const result = dates.map((date) => [date, countMap[date] || 0]);
console.log(result)
You can simply run any loop and find the index of the current element in the submitted array and check if exist then assign date otherwise assign 0 to the array
var dayList = ['2022-12-11', '2023-01-10', '2023-01-09']
var submitted = [ [ '2023-01-09', 1 ], [ '2023-01-10', 3 ] ]
var testData = []
dayList.filter(o => {
const exist = submitted.find(e => e.indexOf(o) != -1)
if(exist){
testData.push([o, exist[1]])
} else {
testData.push([o, 0])
}
});
console.log("your data=", testData)

How to include zero counts in a javascript frequency counting function for histograms

Need some help please - am using the excellent response to this histogram bucketing question as per code below. My question is what is the most elegant way to get my buckets with zero counts represented in the function output?
Current Output is:
[ [ '0', 2 ],
[ '32', 1 ],
[ '64', 2 ],
[ '80', 1 ],
[ '96', 1 ],
[ '112', 1 ] ]
which omits to note buckets 16 and 48 which have zero counts.
My desired output is:
[ [ '0', 2 ],
[ '16', 0 ],
[ '32', 1 ],
[ '48', 0 ],
[ '64', 2 ],
[ '80', 1 ],
[ '96', 1 ],
[ '112', 1 ] ]
All help much appreciated.
function defArrs (){
var arr = [1,16,38,65,78,94,105,124]
var binsize = 16;
var check = Object.entries(frequencies (arr,binsize));
console.log(check);
}
function frequencies(values, binsize) {
var mapped = values.map(function(val) {
return Math.ceil(val / binsize) -1;
});
console.log(mapped);
return mapped.reduce(function (freqs, val, i) {
var bin = (binsize * val);
freqs[bin] ? freqs[bin]++ : freqs[bin] = 1;
return freqs;
}, {});
}
Instead of starting with the empty object for .reduce:
}, {});
// ^^
construct one with all the properties you'll want to be included at the end (starting with a count of 0, of course).
const initialObj = Object.fromEntries(
Array.from(
{ length: 7 },
(_, i) => [i * binsize, 0]
)
);
And pass that as the second parameter to .reduce.
That approach also means that this
freqs[bin] ? freqs[bin]++ : freqs[bin] = 1;
will simplify to
freqs[bin]++;
Or, even better:
const frequencies = (nums, binsize) => {
const mapped = nums.map(num => Math.ceil(num / binsize) - 1;
const grouped = Object.fromEntries(
{ length: 7 },
(_, i) => [i * binsize, 0]
);
for (const val of mapped) {
grouped[binsize * val]++;
}
return grouped;
};

How to loop/iterate over a 2D array using every()?

I cannot find a solution that uses method every(). I want to see if each coordinate (both x and y) is <= 10. So, the following example should return true.
Here is my code:
const shipLocation = [ [ 2, 3 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 6, 3 ] ]
const outOfBounds = function (shipLocation) {
Array.every(locationPoint =>
// code here!
locationPoint <= 10;
);
};
Thank you.
const shipLocation = [ [ 2, 3 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 6, 3 ] ]
const outOfBounds = shipLocation.every(cords=> (cords[0]<=10) && (cords[1]<=10))
You need to return a value (boolean: true or false) from your function.
You have nested arrays so you need to use every on each of them and check that values inside those arrays are less or equal to 10 also by using every again, making sure you return true or false from that callback too.
const shipLocation=[[2,1],[3,3],[4,3],[5,3],[6,3]]
const shipLocation2=[[2,41],[3,3],[4,3],[5,3],[6,3]];
function outOfBounds(shipLocation) {
// For every ship location array
return shipLocation.every(arr => {
// Return whether every value is <= 10
return arr.every(el => el <= 10);
});
};
console.log(outOfBounds(shipLocation));
console.log(outOfBounds(shipLocation2));
You can use the flat() function to make the 2d array into a 1d array:
const shipLocation = [ [ 2, 3 ], [ 3, 3 ], [ 4, 3 ], [ 5, 3 ], [ 6, 3 ] ];
const outOfBounds =
shipLocation.flat().every(locationPoint =>
locationPoint <= 10 // do not put ";"
);
console.log(outOfBounds);

How to merge two 2 dimensional arrays with Jquery

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!

Cartesian product without duplicates

I am using a cartesian product function that given [1], [1,2,3], [1,2,3] returns 9 combinations:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 1, 2 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 1, 3 ],
[ 1, 2, 3 ],
[ 1, 3, 3 ] ]
But I need to remove those with the same items regardless of the order, so [ 1, 3, 1 ] and [ 1, 1, 3 ] are the same to me. The result should contain 6 items:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 3, 3 ] ]
I can write a function that compares all possible pairs with _.xor, but for larger numbers it will probably be very inefficient. Is there a good way in Javascript to do this? An efficient way to compare all possible pairs or an algorithm for cartesian product without duplicates?
sort each array of the cartesian product
[ 1, 2, 1 ] -> [1 , 1 , 2]
[ 1, 1, 2 ] -> [1 , 1 , 2]
then gather these sorted arrays into a set, that will remove the duplicates.
Of course, you can do that while constructing the cartesian product rather than afterward.
JavaScript has Set and Map, however they compare objects and arrays by reference rather than by value, so you cannot take advantage of it directly. The idea is to use a key function which sorts and json encodes the items before putting it in a set.
pure ES5:
function product(sets) {
if (sets.length > 0) {
var head = sets[0];
var tail = product(sets.slice(1));
var result = [];
head.forEach(function(x) {
tail.forEach(function(xs) {
var item = xs.slice(0);
item.unshift(x);
result.push(item);
});
});
return result;
} else {
return [[]];
}
}
function myKeyFn(item) {
return JSON.stringify(item.slice(0).sort());
}
function uniqBy(items, keyFn) {
var hasOwn = Object.prototype.hasOwnProperty, keyset = {};
return items.filter(function(item) {
var key = keyFn(item);
if (hasOwn.call(keyset, key)) {
return false;
} else {
keyset[key] = 1;
return true;
}
});
}
function uniqProduct(sets) {
return uniqBy(product(sets), myKeyFn);
}
function log(x) {
console.log(x);
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(x));
document.body.appendChild(pre);
}
log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
<pre></pre>
lodash + modern JavaScript:
// Note: This doesn't compile on current babel.io/repl due to a bug
function product(sets) {
if (sets.length > 0) {
const [x, ...xs] = sets;
const products = product(xs);
return _.flatMap(x, head => products.map(tail => [head, ...tail]));
} else {
return [[]];
}
}
function uniqProduct(sets) {
return _.uniqBy(product(sets), x => JSON.stringify(x.slice(0).sort()));
}
console.log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
JavaScript has set data structure.
So store your results in a set where each element of the set is a collection of pairs of numbers from the original sets along with the number of times that number occurs.
So your result would look something like this:
[
{1:3},
{1:2, 2: 1},
{ 1:2, 3:1},
{ 1:1, 2:2},
{ 1:1, 2:1, 3:1},
{ 1:1, 3:2 } ]
This way, you won't be able to add the object a second time to the set.

Categories

Resources