How to do Math.random() in for-loop with different values? - javascript

I try to fill the array s with 9999 different sets of values m[i][random], here is the code:
let m = [[22,0],[53,0],[64,0],[45,0],[34,0]];
let l = m.length;
let s = [];
for (let j = 0; j < 9999; j++)
{
for(let i = 0; i < m.length; i++)
{
let x = Math.floor(Math.random()*l);
m[i][1] = x;
}
s.push(m);
}
But i get the same values:
console.log(s)
[ [ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ],
[ [ 22, 0 ], [ 53, 2 ], [ 64, 0 ], [ 45, 4 ], [ 34, 1 ] ], ...]
What am I doing wrong? How to fix it?

Create the m subarray inside the loop (so you have a separate subarray for each iteration), not outside of it - outside, you've only created a single array in memory that each index points to.
let s = [];
for (let j = 0; j < 9999; j++)
{
let m = [[22,0],[53,0],[64,0],[45,0],[34,0]];
let l = m.length;
for(let i = 0; i < m.length; i++)
{
let x = Math.floor(Math.random()*l);
m[i][1] = x;
}
s.push(m);
}
Or, more functionally and all at once with Array.from:
const s = Array.from(
{ length: 2 },
() => [[22,0],[53,0],[64,0],[45,0],[34,0]]
.map(([num]) => [num, Math.floor(Math.random() * 5)])
);
console.log(s);

Related

change all the elements of my array repeating the last one I added

when I try to add the new element to the array it changes the rest of the elements by repeating the last one I added
I'm learning to program in java script and I found this error not because it occurs can someone explain it to me
input=`^>v<`
input=input.split("")
var coordinates=[0,0]
var positions=[]
y=0
v=0
for (x in input){
v+=1
x=input[x]
if (x=="^"){
coordinates[1]+=1
}
if (x=="v"){
coordinates[1]-=1
}
if (x==">"){
coordinates[0]+=1
}
if (x=="<"){
coordinates[0]-=1
}
boolean=positions.indexOf(coordinates)
positions.push(coordinates)
console.log(coordinates)
}
console.log(positions)
output
[ [ 0, 1 ] ]
[ [ 1, 1 ], [ 1, 1 ] ]
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ]
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]

Create array data structure from nested object of arrays in JS

I have a data structure as follows:
UPDATED: to have more than one object in innerValues
const data = {
"dates": [
"2015-09-09T00:00:00",
"2015-09-09T00:10:00",
"2015-09-09T00:20:00",
],
"innerValues": [
{
"name": "Name_1",
"value": [
104,
105,
107,
]
},
{
"name": "Name_2",
"value": [
656,
777,
145,
]
}],
}
I would like to create an output like:
const outPut = [
["2015-09-09T00:00:00", 'Name_1', 104 ],
["2015-09-09T00:10:00", 'Name_1', 105 ],
["2015-09-09T00:20:00", 'Name_1', 107 ],
["2015-09-09T00:00:00", 'Name_2', 104 ],
["2015-09-09T00:10:00", 'Name_2', 105 ],
["2015-09-09T00:20:00", 'Name_2', 107 ]
]
So far I have this, I know I could do this with forEach etc also - but as an example.
const m = data.dates;
let arr = [];
for (var i = 0; i < m.length; i++) {
arr[i] = new Array(m[i]);
}
console.log(arr);
This gives:
0: ['2021-09-09T00:00:00']
1: ['2021-09-09T00:10:00']
2: ['2021-09-09T00:20:00']
Which is where I want to start, however if I map over inner.values and try to create an new array from that, it does not return three separate arrays but one.e.g
const newArray = x.forEach(inner => console.log(new Array(inner)))
Output
0: (3) [104, 105, 107]
How could I achieve the above desired structure.
You can use reduce and map to loop over innerValues and their values
const dates = data.dates
const newArr = data.innerValues.reduce((acc, cur, i) => {
acc.push(cur.value.map((value, i) => ([dates[i], cur.name, value])));
return acc;
}, []).flat()
console.log(newArr)
<script>
const data = {
"dates": [
"2015-09-09T00:00:00",
"2015-09-09T00:10:00",
"2015-09-09T00:20:00",
],
"innerValues": [{
"name": "Name_1",
"value": [
104,
105,
107,
]
},
{
"name": "Name_2",
"value": [
656,
777,
145,
]
}
],
}
</script>

My for loop is not working properly however I have no idea why

So basically I'm writing a script that takes in a credit card number and outputs the provider name. (Also if im doing this in an overly complicated way advice is appreciated)
But my initial for loop to iterate over each object is not working. It will get to 3 (even though the length of the arr is 8) and then just stop...
I am dumbfounded as I have re-read the code for an hour now, checked everything I could think of but am just hitting a wall. Any help would be much appreciated!
The Code
var detectNetwork = function(cardNumber) {
var splitDigits = cardNumber.split('');
var length = splitDigits.length;
var first = splitDigits[0];
var second = splitDigits[1];
var firstTwo = splitDigits[0] + splitDigits[1];
var firstThree = splitDigits[0] + splitDigits[1] + splitDigits[2];
var firstFour = splitDigits[0] + splitDigits[1] + splitDigits[2] + splitDigits[3];
var firstSix = splitDigits[0] + splitDigits[1] + splitDigits[2] + splitDigits[3] + splitDigits[4] + splitDigits[5];
var checkProvider = [
{
name: 'American Express',
length: [ 15 ],
prefixLength: [ 2 ],
prefixType: 'simple',
prefix: [ 34, 37 ]
},
{
name: 'Diner\'s Club',
length: [ 14 ],
prefixLength: [ 2 ],
prefixType: 'simple',
prefix: [ 38, 39 ]
},
{
name: 'Visa',
length: [ 13, 16, 19 ],
prefixLength: [ 1 ],
prefixType: 'simple',
prefix: [ 4 ]
},
{
name: 'MasterCard',
length: [ 16 ],
prefixLength: [ 2 ],
prefixType: 'range',
prefix: [ 51, 55 ]
},
{
name: 'Discover',
length: [ 16, 19 ],
prefixLength: [ 2, 3, 4],
prefixType: 'complexRange',
prefix: [ 6011, [ 644, 649 ], 65 ]
},
{
name: 'Maestro',
length: [ 12, 13, 14, 15, 16, 17, 18, 19],
prefixLength: [ 4 ],
prefixType: 'simple',
prefix: [ 5018, 5020, 5038, 6304 ]
},
{
name: 'China UnionPay',
length: [ 16, 17, 18, 19 ],
prefixLength: [ 3, 4, 6 ],
prefixType: 'complexRange',
prefix: [ [ 622126, 622925 ], [ 624, 626 ], [ 6282, 6288 ] ]
},
{
name: 'Switch',
length: [ 16, 18, 19 ],
prefixLength: [ 4, 6 ],
prefixType: 'simple',
prefix: [ 4903, 4905, 4911, 4936, 564182, 633110, 6333, 6759 ]
}
];
for(var i = 0; i < checkProvider.length; i++) {
var currentProvider = checkProvider[i];
var name = currentProvider.name;
var lengthOptions = currentProvider.length;
var prefixLengthOptions = currentProvider.prefixLength;
var prefixType = currentProvider.prefixType;
var prefixOptions = currentProvider.prefix;
for(var j = 0; j < lengthOptions.length; j++) {
var currentLength = lengthOptions[j];
if (currentLength === length) {
//Use first
for (var y = 0; y < prefixLengthOptions.length; y++) {
var currentPrefixLength = prefixLengthOptions[y];
if(currentPrefixLength === 1) {
if (first === '4') {
if (firstFour !== 4903 && firstFour !== 4905 && firstFour !== 4911 && firstFour !== 4936) {
return name;
}
}
}
if (currentPrefixLength === 2) {
if (prefixType === 'complexRange') {
console.log(name);
}
if (prefixType === 'simple') {
for (var i = 0; i < prefixOptions.length; i++) {
if (firstTwo === prefixOptions[i].toString()) {
return name;
}
}
}
if (prefixType === 'range') {
var min = prefixOptions[0];
var max = prefixOptions[1];
for (var i = min; i < max + 1; i++) {
if (firstTwo === i.toString()) {
return name;
}
}
}
}
}
}
}
}
}
Your test detectNetwork('6011123456789303') logs Discover if you make the following small changes to your code:
Replace all var with const.
Declare all loop index variables with let. For example, for (let i = 0;.
The issue with your current code is that you have var i redeclared within the same context. According to documentation, these cases do not trigger an error, however the behavior will be confusing when the values are overwritten, which is your case.
The suggestion is to rename the other var i to something else, and that should solve your problem.
Another option is to use let i which will make the context more strict.
So this code would work best (I made it so if always returns the name):
const detectNetwork = function(cardNumber) {
const splitDigits = cardNumber.split('');
const length = splitDigits.length;
const first = splitDigits[0];
const second = splitDigits[1];
const firstTwo = splitDigits[0] + splitDigits[1];
const firstThree = splitDigits[0] + splitDigits[1] + splitDigits[2];
const firstFour = splitDigits[0] + splitDigits[1] + splitDigits[2] + splitDigits[3];
const firstSix = splitDigits[0] + splitDigits[1] + splitDigits[2] + splitDigits[3] + splitDigits[4] + splitDigits[5];
const checkProvider = [
{
name: 'American Express',
length: [ 15 ],
prefixLength: [ 2 ],
prefixType: 'simple',
prefix: [ 34, 37 ]
},
{
name: 'Diner\'s Club',
length: [ 14 ],
prefixLength: [ 2 ],
prefixType: 'simple',
prefix: [ 38, 39 ]
},
{
name: 'Visa',
length: [ 13, 16, 19 ],
prefixLength: [ 1 ],
prefixType: 'simple',
prefix: [ 4 ]
},
{
name: 'MasterCard',
length: [ 16 ],
prefixLength: [ 2 ],
prefixType: 'range',
prefix: [ 51, 55 ]
},
{
name: 'Discover',
length: [ 16, 19 ],
prefixLength: [ 2, 3, 4],
prefixType: 'complexRange',
prefix: [ 6011, [ 644, 649 ], 65 ]
},
{
name: 'Maestro',
length: [ 12, 13, 14, 15, 16, 17, 18, 19],
prefixLength: [ 4 ],
prefixType: 'simple',
prefix: [ 5018, 5020, 5038, 6304 ]
},
{
name: 'China UnionPay',
length: [ 16, 17, 18, 19 ],
prefixLength: [ 3, 4, 6 ],
prefixType: 'complexRange',
prefix: [ [ 622126, 622925 ], [ 624, 626 ], [ 6282, 6288 ] ]
},
{
name: 'Switch',
length: [ 16, 18, 19 ],
prefixLength: [ 4, 6 ],
prefixType: 'simple',
prefix: [ 4903, 4905, 4911, 4936, 564182, 633110, 6333, 6759 ]
}
];
for(let i = 0; i < checkProvider.length; i++) {
let currentProvider = checkProvider[i];
let name = currentProvider.name;
let lengthOptions = currentProvider.length;
let prefixLengthOptions = currentProvider.prefixLength;
let prefixType = currentProvider.prefixType;
let prefixOptions = currentProvider.prefix;
for(let j = 0; j < lengthOptions.length; j++) {
let currentLength = lengthOptions[j];
if (currentLength === length) {
//Use first
for (let y = 0; y < prefixLengthOptions.length; y++) {
let currentPrefixLength = prefixLengthOptions[y];
if(currentPrefixLength === 1) {
if (first === '4') {
if (firstFour !== 4903 && firstFour !== 4905 && firstFour !== 4911 && firstFour !== 4936) {
return name;
}
}
}
if (currentPrefixLength === 2) {
if (prefixType === 'complexRange') {
return(name);
}
if (prefixType === 'simple') {
for (let i = 0; i < prefixOptions.length; i++) {
if (firstTwo === prefixOptions[i].toString()) {
return name;
}
}
}
if (prefixType === 'range') {
let min = prefixOptions[0];
let max = prefixOptions[1];
for (let i = min; i < max + 1; i++) {
if (firstTwo === i.toString()) {
return name;
}
}
}
}
}
}
}
}
}
var n = detectNetwork('6011123456789303');
console.log(n); // Discover

Do you know how to loop this? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
example we have this js array (some kind like lat, lng):
items = [
[aa,aa],
[bb,bb],
[cc,cc]
]
the result that i expected should be like this:
A = [
[aa,aa],
[bb,bb]
]
B = [
[bb,bb],
[cc,cc]
]
You are trying to iterate over two consecutive elements (arrays), you can use ruby_cons.
Note: This is a Ruby solution to iterate over consecutive elements.
items.each_cons(2) do |arr|
p arr
end
in javascript, you can try sth like,
> items
[ [ 42.32, 47.32 ], [ 49.434, 41.343 ], [ 43.34, 43.45 ] ]
> container = []
[]
> for(var i = 0; i<items.length-1; i++) {
... container.push(items.slice(i, i+2));
... }
2
> container[0]
[ [ 42.32, 47.32 ], [ 49.434, 41.343 ] ]
> container[1]
[ [ 49.434, 41.343 ], [ 43.34, 43.45 ] ]
more generalized solution, inspired from ruby's each_cons(n) enumerable method.
> each_cons = function(enm, cons_size) {
... var results = [];
... /*
... * checking numericality like typeof cons_size == 'number'
... * might be useful. but i'am skipping it.
... */
... cons_size = (cons_size < 1 ? 1 : cons_size );
... // setting default to 2 might be more reasonable
... for (var i=0; i<=enm.length - cons_size; i++) {
..... results.push(enm.slice(i, i+cons_size));
..... }
... return results;
... }
[Function: each_cons]
> x = [1,2,3,4,5,6,7,8,9,0];
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ]
> each_cons(x, 0)
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ], [ 8 ], [ 9 ], [ 0 ] ]
> each_cons(x, 1)
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ], [ 8 ], [ 9 ], [ 0 ] ]
> each_cons(x, 2)
[ [ 1, 2 ],
[ 2, 3 ],
[ 3, 4 ],
[ 4, 5 ],
[ 5, 6 ],
[ 6, 7 ],
[ 7, 8 ],
[ 8, 9 ],
[ 9, 0 ] ]
> each_cons(x, 3)
[ [ 1, 2, 3 ],
[ 2, 3, 4 ],
[ 3, 4, 5 ],
[ 4, 5, 6 ],
[ 5, 6, 7 ],
[ 6, 7, 8 ],
[ 7, 8, 9 ],
[ 8, 9, 0 ] ]
>
> x= "hippopotomonstrosesquipedaliophobia"; //https://en.wiktionary.org/wiki/hippopotomonstrosesquipedaliophobia
'hippopotomonstrosesquipedaliophobia'
> each_cons(x, 3)
[ 'hip',
'ipp',
'ppo',
'pop',
'opo',
'pot',
'oto',
'tom',
'omo',
'mon',
'ons',
'nst',
'str',
'tro',
'ros',
'ose',
'ses',
'esq',
'squ',
'qui',
'uip',
'ipe',
'ped',
'eda',
'dal',
'ali',
'lio',
'iop',
'oph',
'pho',
'hob',
'obi',
'bia' ]
>
> x = [[1,2], ['a', 'b'], [2,3,4, {a: 5}]]
[ [ 1, 2 ], [ 'a', 'b' ], [ 2, 3, 4, { a: 5 } ] ]
> each_cons(x, 2)
[ [ [ 1, 2 ], [ 'a', 'b' ] ],
[ [ 'a', 'b' ], [ 2, 3, 4, [Object] ] ] ]

How to find sum of duplicate values in an array using javascript

I have the following array with me. And my aim is to create a new array by removing duplicate values from this array.
var xDataValuesdash = [ [ 'Anantapur', 10, '#C21466' ],
[ 'Anantapur', 20, '#A983D0' ],
[ 'Chittoor', 30, '#A993D0' ],
[ 'Anantapur', 30, '#544DDF' ],
[ 'Anantapur', 4, '#A994D0' ],
[ 'Chittoor', 40, '#544BDF' ] ];
ie, The resultant array must be
var new_xDataValuesdash = [[ 'Anantapur', 64, '#C21466' ],
[ 'Chittoor', 70, '#544BDF' ]];
While removing duplicates its value must be added to the unqiue value.
Try this
var xDataValuesdash = [ [ 'Anantapur', 10, '#C21466' ],
[ 'Anantapur', 20, '#A983D0' ],
[ 'Chittoor', 30, '#A993D0' ],
[ 'Anantapur', 30, '#544DDF' ],
[ 'Anantapur', 4, '#A994D0' ],
[ 'Chittoor', 40, '#544BDF' ] ];
var sum = {},result;
for (var i=0,c;c=xDataValuesdash[i];++i) {
if ( undefined === sum[c[0]] ) {
sum[c[0]] = c;
}
else {
sum[c[0]][1] += c[1];
}
}
result = Object.keys(sum).map(function(val) { return sum[val]});
alert(JSON.stringify(result));
Here is a simple solution, not very sophisticated but gets the job done.
var a = [
['Anantapur', 10, '#C21466'],
['Anantapur', 20, '#A983D0'],
['Chittoor', 30, '#A993D0'],
['Anantapur', 30, '#544DDF'],
['Anantapur', 4, '#A994D0'],
['Chittoor', 40, '#544BDF']
];
var findDuplicatesAndSum = function(inptArr) {
var duplicateIndex = {};
var outputArr = [];
for (var i = 0; i < inptArr.length; i++) {
var item = inptArr[i];
var collisionIndex = duplicateIndex[item[0]];
if (collisionIndex > -1) {
outputArr[collisionIndex][1] += item[1];
} else {
outputArr.push(item);
duplicateIndex[item[0]] = outputArr.length - 1;
}
}
console.log(outputArr);
return outputArr;
};
findDuplicatesAndSum(a);
This code might helps.
var xDataValuesdash = [
[ 'Anantapur', 10, '#C21466' ],
[ 'Anantapur', 20, '#A983D0' ],
[ 'Chittoor', 30, '#A993D0' ],
[ 'Anantapur', 30, '#544DDF' ],
[ 'Anantapur', 4, '#A994D0' ],
[ 'Chittoor', 40, '#544BDF' ] ];
var new_DataValuesdash = [];
for(var i=0; i < xDataValuesdash.length;i++){
if(new_DataValuesdash[xDataValuesdash[i][0]] == undefined) {
new_DataValuesdash[xDataValuesdash[i][0]] = xDataValuesdash[i];
}
else {
// new_DataValuesdash[xDataValuesdash[i][0]] = [];
new_DataValuesdash[xDataValuesdash[i][0]][1] = new_DataValuesdash[xDataValuesdash[i][0]][1] + xDataValuesdash[i][1];
}
}
console.log(new_DataValuesdash);
You can use for..of loop, Array.prototype.some(), Array.prototype.forEach()
var xDataValuesdash = [ [ 'Anantapur', 10, '#C21466' ],
[ 'Anantapur', 20, '#A983D0' ],
[ 'Chittoor', 30, '#A993D0' ],
[ 'Anantapur', 30, '#544DDF' ],
[ 'Anantapur', 4, '#A994D0' ],
[ 'Chittoor', 40, '#544BDF' ] ];
var res = [];
for (var prop of xDataValuesdash) {
!res.some(value => value && value[0] === prop[0])
? res.push(prop)
: res.forEach(value => {
if (value[0] === prop[0]) value[1] += prop[1]
});
}
console.log(res);

Categories