Print elements of object array in Javascript - javascript

I have this array of objects to count element frequency in another array using for loop which prints correct output.
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
There is another array of arrays:
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ',counts[s]); //prints undefined
counter = counts[s];
}
i++;
}
The array of arrays "holder_text_array" consists of elements whose frequency I need to get in the while loop. Can someone tell me where am I wrong?

The frequency is stored in s not in counts[s]
You're logging counts[s] where var s = counts[holder_text_array[i][1]];
You've already got the element from counts in s. Just log the value of s
Apart from that the function works!
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ', s); // CHANGED THIS TO JUST `s`
counter = counts[s];
}
i++;
}

You could take a recursive approach and call the count function again for (nested) arrays with the same counts object.
The result contains the counts of each element.
function getCounts(array, counts = {}) {
for (let i = 0; i < array.length; i++) {
const value = array[i];
if (Array.isArray(value)) {
getCounts(value, counts);
continue;
}
if (!counts[value]) counts[value] = 0;
counts[value]++;
}
return counts;
}
console.log(getCounts([["a", 50, 0], ["b", 0, 0]]));

I figured out the problem. Issue is in initialization.
I changed the following:
var s = counts[holder_text_array[i][1]];
counter = counts[s];
It works this way:
var s = holder_text_array[i][1];
counter = counts[s];

Related

Access the array Object property value through for loop

I want access the object property which in inside array how to access that through a for loop ex:
arr[{A:1},{A:2},{B:3},{C:3}]
i want sum of each object.
let arr = [{A:1},{A:2},{B:3},{C:3}]
let sum = arr.reduce((ac, o) => ac + Object.values(o)[0], 0);
console.log(sum);
If you have same known key in object, then you can try this
var data = [{a:6},{a:8},{a:9}];
var dataLength = data.length;
var total = 0;
var i = 0;
while(i < dataLength){
total += data[i]["a"];
i++;
}
If you have object with unkown keys / dynamic keys, then use this,
var data = [{a:6},{b:8},{c:9,e:5}];
var dataLength = data.length;
var total = 0;
var i = 0;
while(i < dataLength){
for(var propName in data) {
if(data.hasOwnProperty(propName)) {
var propValue = data[propName];
total += propValue;
}
}
i++;
}

javascript array value is changing after it has been pushed

I am trying to debug the code below.
It is supposed to create a 2d-array, with all of the permutations of the input string.
It starts off great, and the initial string is pushed to the array, but after I run the reverse function in step 4, the value in strArr changes from having a length of 3 to a length of 2. basically like it is skipping the concat in the reverse function, but when I ran it in the debugger, z has a length of 3 after the concat, but then when the function returns it, the length becomes 2 again.
any help would be appreciated.
function permAlone(str) {
var perms = [];
var totalPerms = factorial(str.length);
var strCodes = converter(str);
var strArr = [];
strArr.push(strCodes);
// overall loop
for (var X = 0; X < totalPerms; X++) {
//step 1
var largestI = -1;
for (var i = 0; i < strCodes.length - 1; i++) {
if (strCodes[i] < strCodes[i + 1]) {
largestI = i;
}
}
//if none found break loop
if (largestI == -1) {
break;
}
//step 2
var largestJ = -1;
for (var j = 0; j < strCodes.length; j++) {
if (strCodes[largestI] < strCodes[j]) {
largestJ = j;
}
}
//step 3
swap(strCodes, largestI, largestJ);
//step 4
strCodes = reverse(strCodes, largestI);
//step 5 push to array
strArr.push(strCodes);
}
console.log(strArr);
return strArr;
}
function factorial(x) {
for (var i = x - 1; i > 0; i--) {
x *= i;
}
return x;
}
function converter(x) {
var temp = [];
for (var i = 0; i < x.length; i++) {
temp.push(x.charCodeAt(i));
}
return temp;
}
function swap(a, i, j) {
var temp = a[i];
a[i] = a[j];
a[j] = temp;
}
function reverse(z, a) {
var endArr = z.splice(a+1);
endArr.reverse();
z = z.concat(endArr);
return z;
}
debugger;
permAlone('abc');
The reverse function returns a new array and does not manipulate the existing. You need to change your code to the following:
endArr = endArr.reverse();
It looks like it was an issue with having a shallow copy of the array.
I added z = z.slice(); to the reverse function and it fixed the issue.

How do I get a previous value of a random generated numbers 1 to 10?

I have a random generator from 1 to 10 that produces non repeating values
I am trying to get the previous value.
So if current is 5 and then 8
Previous 8 and next is 9, etc
This is my code:
var randomNumbers = [];
var numRandoms = 11;
var myVar = setInterval(randomUnique1to10, 5000);
function randomUnique1to10() {
// refill the array if needed
if (!randomNumbers.length) {
for (var i = 1; i < numRandoms; i++) {
randomNumbers.push(i);
}
}
var index = Math.floor(Math.random() * randomNumbers.length);
var val = randomNumbers[index];
if (i === 1) { // i would become 0
i = randomNumbers.length; // so put it at the other end of the array
}
i = i - 1; // decrease by one
previous = randomNumbers[i]; // give us back the item of where we are now
randomNumbers.splice(index, 1);
Thank you
This is totally what you're looking for. Hope it helps!.
var randomNumbers = [];
var numRandoms = 11;
var myVar = setInterval(randomUnique1to10, 1000);
shuffle = function(o){
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
var finalArray = shuffle([1, 2, 3, 4,5,6,7,8,9,10]);
function randomUnique1to10() {
// refill the array if needed
if (!randomNumbers.length) {
for (var i = 1, l = 11; i < l; i++) { }
}
// var finalArray = shuffle(randomNumbers);
document.write(finalArray + "<br/>");
randomNumbers = finalArray;
var index = Math.floor(Math.random() * randomNumbers.length);
var val = randomNumbers[index];
if (i === 1) { // i would become 0
i = randomNumbers.length; // so put it at the other end of the array
}
x = index-1; // decrease by one
current = randomNumbers[randomNumbers.length - 1]; // give us back the item of where we are now
previous = randomNumbers[randomNumbers.length - 2];
if(previous === undefined)
{
previous = "n/a";
}
randomNumbers.pop();
if(randomNumbers.length <= 0){
finalArray = shuffle([1, 2, 3, 4,5,6,7,8,9,10]);
}
document.write("Current >> " + current + " and previous = " +previous + "<br/>")
}
try this:
var randomNumbers = [];
var numRandoms = 11;
var myVar = setInterval(randomUnique1to10, 5000);
var x;
function randomUnique1to10() {
// refill the array if needed
if (!randomNumbers.length) {
for (var i = 1; i < numRandoms; i++) {
randomNumbers.push(i);
}
}
var index = Math.floor(Math.random() * randomNumbers.length);
var val = randomNumbers[index];
if (i === 1) { // i would become 0
i = randomNumbers.length; // so put it at the other end of the array
}
x = index-1; // decrease by one
previous = randomNumbers[x]; // give us back the item of where we are now
var res = randomNumbers.splice(index, 1);
console.log("result: "+res);
console.log("prev : "+previous);
console.log("Rand : "+randomNumbers);
}
NOTE:
this code have, one problem, if res = min(array) then prev will become unidentify
The question lack a bit of clarity. From the question what I understood is,
The values in the array are non repeating
You have a value at variable current and you want to find the previous value of the current which is stored in the array
And I will answer from what I understood. Using indexOf() gives you the index of current element from the array and you just need to subtract 1 from it to get the previous.
var array = [1, 9, 2, 8, 3, 7, 4, 6, 5];
var current = 8;
var currentIndex = array.indexOf(current);
var previous = currentIndex !== 0 ? array[currentIndex-1] : 'N/A';
document.write('Previous Value: ', previous)

Google Apps Scripts setValues() incorrect height error

I've looked at some other questions similar to this, but I'm getting my array in a unique way and I can't figure out for the life of my how to change it to a 2D array.
//Special function for adding arrays, just use sumArray on first array with second array in parenthesis
//==========================================
Array.prototype.sumArray = function (arr) {
var sum = this.map(function (num, idx) {
return num + arr[idx];
});
return sum;
}
var array1 = [1,2,3,4];
var array2 = [5,6,7,8];
var sum = array1.sumArray(array2);
Logger.log("sum: " + sum);
//==========================================
var calc = ss.getRangeByName( "calc" );
var target = ss.getRangeByName( "target" );
var current = ss.getRangeByName( "current" );
var left = ss.getRangeByName( "left" );
var gainedEVs = calc.getValues();
var goalEVs = target.getValues();
var oldEVs = current.getValues();
var leftEVs = left.getValues();
//Make everything ints
//==========================================
for(var i = 0; i < oldEVs.length; i++) {
Logger.log(oldEVs.length);
oldEVs[i] = parseInt(oldEVs[i]);
}
for(var i = 0; i < gainedEVs.length; i++) {
gainedEVs[i] = parseInt(gainedEVs[i]);
}
for(var i = 0; i < goalEVs.length; i++) {
goalEVs[i] = parseInt(goalEVs[i]);
}
for(var i = 0; i < leftEVs.length; i++) {
leftEVs[i] = parseInt(leftEVs[i]);
}
//==========================================
var newEVs = [[oldEVs.sumArray(gainedEVs)]];
var newLeft = [[goalEVs.subArray(newEVs)]];
//Now I try to set values and I get the error
current.setValues(newEVs);
I've tried changing the setValues to setValues([newEVs]); but that doesn't work either. Any clue on how I can get my array of newEVs to be the correct height? It has the right number of values, but those values are being stored in columns, not rows. (in this case all of my ranges are 6 rows 1 col)
Since your ranges are small, you don't have to worry too much about performance, so you can convert them from rows to columns using a loop:
var column = [];
for (var i=0; i<newEVs.length; i++){
column.push([newEVs[i]]);
}
current.setValues(column);

Defining a 3D array in JavaScript

I tried to define a 3D array on Google Sheet, but even though I'm using the .slice() method it keeps passing the array by reference.
var temp = [];
for (var a = 0; a<archetypesAll.length; a++) {temp[a] = [0, a].slice();};
var archRank = [];
for (var a = 0; a<21; a++) {archRank[a]= temp.slice();};
archRank[2][1][0] = 'Test';
I want to edit a single element of the matrix but instead the code above just fills every row with the exact same value ('Test'):
3DMatrix[x][1][0] = 'Test'
You can't just copy a multidimensional array by calling slice at the top level, because that will not deep-copy the whole. You have to write your own deepCopy methid, like this:
function allocate(mainDim, ...dims) {
const result = new Array(mainDim);
for (let i = 0; i < result.length; i++) {
result[i] = dims.length > 0 ? allocate(...dims) : 0;
}
return result;
}
function deepCopy(matrix, dims) {
return dims > 1 ? matrix.map(row => deepCopy(row, dims - 1)) : matrix.slice();
}
function test() {
const mx1 = allocate(3,2,2);
mx1[2][1][0] = "Test";
console.log(JSON.stringify(mx1));
const mx2 = deepCopy(mx1, 3);
mx2[2][1][0] = "Copied";
console.log(JSON.stringify(mx1));
console.log(JSON.stringify(mx2));
}
test();
var array = ["Test", "Test"];
var array3d = [[array.slice(0)],[[array.slice(0)]]];
array3d[0][0][0] = "Changed";
console.log(JSON.stringify(array3d)); //[[["Changed","Test"]],[[["Test","Test"]]]]
Try with this instead of slice to get a new array instead of reference:
var temp = [];
for (var a = 0; a < archetypesAll.length; a++) {
temp[a] = JSON.parse(JSON.stringify([0, a]));
}
var archRank = [];
for (var a = 0; a < 21; a++) {
archRank[a]= temp.slice();
}
archRank[2][1][0] = 'Test';

Categories