I have a nested array structure that looks like this below. Lets call it arr:
The innermost array has a key and value pair. But as it can be seen, the values are only from 3-7. I need to fill this innermost array with values 0-9 in the key column and populate them to 0 if the key doesn't already exist. I tried creating a separate array(target) with values [0,9] to check against but have been unsuccessful. I tried to do something like this but I am getting an error:
var target = [0,1,2,3,4,5,6,7,8,9];
for(let i =0; i < target.length; i++){
for(let j =0; j < arr.length; j++){
for(let k =0; k < arr[j].values.length; k++){
if (miss_rate_arr[i] in rating_count[j].values[k].key === false){
rating_count[j].values.push({key:miss_rate_arr[i], value:0});
}
}
}
}
console.log(rating_count);
This is not only checking that particular value at that 0 location and I understand the problem. I am just not sure how to fix it. I am expecting the end result to look something like this below. Thank you in advance
I'm not exactly sure what youre going for,
If you're going for a more general approach and want to keep the target array,
this is more like what you posted, and you'd need to sort it afterwards to get the array in the order you posted..
let target = [0,1,2,3,4,5,6,7,8,9];
for(let i = 0; i < target.length; i++){
if (arr.filter(x => x.key == target[i]).length == 0){
arr.push({key:target[i], value:0});
}
}
arr.sort((a,b) => a.key - b.key);
But if target is always 0-9, you could skip the target array and just loop from 0 to the max key you're aiming for.
that way the test for the value is more simple (you can just check if the key matches the index) and since you have to add it at the correct index, you keep it sorted..
let maxKey = 9;
for(let i = 0; i <= maxKey; i++){
if (arr.length > i && arr[i].key != i || arr.length == i){
arr.splice(i, 0, {key: i, value:0});
}
}
Related
For example, I have such array: var number2 = [1,3,4,1,5,6,3] and I want to output only repeated elements such as 1 and 3 without any method. My code is as follows:
for(let i=0; i<number2.length; i++){
for(let j=0; j<number2.length; j++){
if([i]!==[j] && number2[i]===number2[j]){
console.log(number2[i]);
}
}
}
But it doesn't work how I want.
[i] !== [j] Should be just i !== j.
number2[i] === number2[j] is correct.
If you need less complexity [instead of O(n^2), O(n)] you can use a map over there. just loop over the array you have, and put each digit in map with its occurrences.
var map = new Map();
for(var i=0; i<arr.length; i++){
var val = map.get(arr[i]);
// if key found [such as, if the value already exist in array]
if(!isNaN(val))
map.set(arr[i], val+1);
// if key not found[such as, if the value found for the first time in array]
else
map.set(arr[i], 1);
}
// iterate over the map, and print only those value whose occourance is >1.
for(var [key, value] of map){
if(value > 1)
console.log(key);
}
Given an array of integers where every value appears twice except one, find the single, non-repeating value.
Follow up: do so with O(1) space.
1) This is incorrect, the idea is to iterate through twice and compare if any value the first time around is not equal to a the 2nd go around. If not, push the non equal value into a new array and return that.
2) Is forEach pretty much the same as a for-loop?
How could this be rewritten with a forEach?
This is not giving me the output I'd like, which for this example,
should just return 4
CODE
const nonRepeat = arr => {
let newArray = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[i] !== arr[j]) {
newArray.push(arr[i])
}
}
}
return newArray
}
console.log(nonRepeat([2, 5, 3, 2, 1, 3, 4, 5, 1]));
Convert from for loop to forEach loop
for
for (let i = 0; i < arr.length; i++) { [code] }
forEach eliminates need to create the iterative variable ( for example, i) and always checks every element in the array
arr.forEach( [code] )
See Here for Additional Syntax Help
I am trying my hand at Javascript after learning a number of other coding languages.
*Edit* I fixed the problem, I simply had to use the let keyword in both outer for loops which used i as the same name for the iterator variable.
I have a 2D int array with 29 rows, each of which contains an array of length 744 (744 * 29 = 21576 numbers), and I would like to pass each array, or column, into a method that performs math expressions (i.e the mean of all values, the standard deviation, etc) and log the results to my console. When I attempt to do so, the loop only outputs results of the computation of the numbers in the 1st array, and none of the others. I may be wrong, but I have a feeling the solution may have something to do with awaiting for a result and/or exploiting asynchronous behavior, or my misunderstanding of how to deal with an array as an object.
First and foremost, I have written all of my active code within an fs.readFile method, which reads through a JSON file that provides me with my desired data.
fs.readFile('./doc.json', 'utf-8', (err, text) => {...
The resulting data is an array of objects. The following is the hierarchy of information found within the array. I use a triple for loop to access the desired data and populate my 2D array. (I know that this is not nearly the most efficient way of accomplishing this, but I figure it should work nonetheless)
//Array [
//Object {...
//Property: inner Array[
//inner Object {...
//Desired Property: object which contains the desired values{...}
// },...
// ]
// },...
// ]
for(let i = 0; i < dataArray.length; i++){
for(let j = 0; j < dataArray[i].property.length; j++){
let valueArray = Object.values(dataArray[i].property[j].desiredProperty).slice(0);
for(let c = 0; c < valueArray.length; c++;){
arr[c][(i * dataArray[i].property.length) + j] = valueArray[c];
}
}
}
After populating it, I have no problem iterating through the 2D array and simply logging every array of numbers to the console (the following loop is outside of the previous loop)
for(i = 0; i < arr.length; i++){
console.log("array number " + (i + 1) + ": " + arr[i]);
}
However, when I attempt to pass the same array into a GetTotal method (retrieves the total of all numbers in the array) and store the result, the program outputs the mean of the first array of numbers, and immediately ends.
for(i = 0; i < arr.length; i++){
console.log("array number " + (i + 1) + ": " + arr[i]);
let tot = GetTotal(arr[i]);
console.log("\nTotal: " + tot);
}
function GetTotal(nums){
let sum = 0;
for(i = 0; i < nums.length; i++){
sum += nums[i];
}
return sum;
}
Not quite sure how to post pictures here, I'm sure those would be helpful to better visualize the situation
I initialize my 2D array using a Create2DArray method, then populate each new array with zeroes:
var arr= Create2DArray(numRows, numCols);
for(i = 0; i < arr.length; i++){
for(j = 0; j < arr[i].length; j++){
arr[i][j] = 0;
}
}
function Create2DArray(rows,cols){
let newArr = [];
for(i = 0; i < rows; i++){
newArr.push(new Array(cols));
}
return newArr;
}
I would like to see the result of performing the method's computations on ALL arrays of numbers instead of just the first.
Thanks for your time.
I am not sure of have understood what exactly are you looking for. This would be my approach to this kind of problems :
var dataArray = [
{propertyArr : [{prop1 : 1, prop2 : 2}, {prop1 : 1, prop2 : 2}]},
{propertyArr : [{prop1 : 3, prop2 : 4}, {prop1 : 3, prop2 : 4}]},
{propertyArr : [{prop1 : 5, prop2 : 6}, {prop1 : 5, prop2 : 6}]}
]
var valueArray = [1,2,3,4,5,6,7] ;
var resultValues = dataArray.map((element,i) => {
var arr = element.propertyArr.map((object,j) => {
var value = valueArray[object.prop1] + valueArray[object.prop2] ;
return value ;
})
return arr ;
});
resultValues.forEach((elementArr,i) => {
elementArr.forEach((element2Arr,j)=>{
console.log(`resultValues[${i},${j}] : [${resultValues[i][j]}]`) ;
})
})
I am trying to make a multiplayer poker game in Node.js, and I've been having a lot of issues lately. This is a major one. This code is supposed to identify a Straight hand from an array. However, my code apparently isn't universal. I made 2 arrays as test cases and different results are produced when even just of the arrays is identified as a straight. Please help.
Here's the code:
var arr = [9,1,2,11,8,12,10]; // first array
var arr2 = [9,1,8,4,5,3,2]; // second array
var straight = [];
// Removes duplicate elements in an array
/* example:
array = removeDuplicates(array)
*/
function removeDuplicates(arr){
let unique_array = []
for(let i = 0;i < arr.length; i++){
if(unique_array.indexOf(arr[i]) == -1){
unique_array.push(arr[i])
}
}
return unique_array
}
//Sorts the array
arr.sort(function(a,b){return b-a});
//Removes duplicates
arr = removeDuplicates(arr);
// Displays sorted and cleaned up array
console.log(arr)
/*Basic translation: loops through the array
and if the difference between the a term and
the term after it is 1, it will append it to the
array 'straight'. It will break if the difference
is greater than 1. Then it will remove those elements
from the original array and retry to append consecutive
elements in the 'straight' array.
*/
for (var i=1; i<arr.length+1; i++) {
if (arr[i-1] - arr[i] === 1) {
straight.push(arr[i-1],arr[i]); // error occurs at this line
} else if (arr[i-1] - arr[i] > 1){
break; }
if (straight.length === 2) {
arr.splice(arr.indexOf(straight[0]),1)
arr.splice(arr.indexOf(straight[1]),1)
straight = [];
for (var i=1; i<arr.length; i++) {
if (arr[i-1] - arr[i] === 1) {
straight.push(arr[i-1],arr[i]);
}
}
}
};
// There are duplicates and I don't know why sometimes
straight = removeDuplicates(straight)
console.log(straight);
This doesn't work for some reason. But it will work fine ONLY for the first array if you change
straight.push(arr[i-1],arr[i]);
to
straight.push(arr[i-1],arr[i],arr[i]);
It works ONLY for the second array if you switch the variable names:
var arr2 = [9,1,2,11,8,12,10]; // first array
var arr = [9,1,8,4,5,3,2]; // second array
and run the code without further changes, I don't know why it does this. I even went as far as logging the boolean
arr[i-1] - arr[i] === 1
to the console (in the loop, I mean), and it comes out true four times in a row (going through the first 5 indexes of the array), so I don't know why it stops at 11 for the first array and decides 11-10 isn't 1.
your logic is a bit hard to follow - I think the issue you're seeing is due to clearing the straight array in the if (straight.length === 2) part. Here's my shot at simplifying things:
const isStraight = a => {
const uniq = a.filter((val, idx) => a.indexOf(val) === idx);
uniq.sort((a, b) => a-b);
const tries = uniq.length - 4;
for (var i=0; i<tries; i++) {
if (uniq[i + 4] - uniq[i] === 4) {
return true;
}
}
return false;
}
console.log(isStraight([9,1,2,11,8,12,10]));
console.log(isStraight([9,1,8,4,5,3,2]));
console.log(isStraight([2,5,4,3,6,8,7]));
console.log(isStraight([2,5,4,3,6,8,7,10]));
console.log(isStraight([2,5,2,4,7,3,6,8,8,8,8,7]));
console.log(isStraight([1,2,3,4,6,7,8,9,11,12,13,13]))
let arr = [9,1,2,11,8,12,10];
function checkStraight(arr) {
let answer = [];
if(arr.length < 5)
return false;
arr = [...new Set(arr)];
arr.sort(function(a,b){return b-a});
for(let index=0; index < arr.length; index++){
if(answer.length === 5) break;
if(answer.length === 0){
answer.push(arr[index])
}
if(answer[answer.length-1] - arr[index] === 1){
answer.push(arr[index]);
}else{
answer = [];
answer.push(arr[index])
}
}
return answer
}
console.log(checkStraight(arr));
You can try to run thru the code, should be quite simple. Basically instead of comparing between elements inside own array, we compare between two array, and conditionally push the matched straight card into new array
**assumptions: ** Since we are playing poker, assuming once 5 consecutive card been found, it's consider a straight and no further checking needed
I've been trying the Number.isInteger() method on chrome console.
and after doing a for loop and checking the result with the console.log(arr); I'm getting an array with only one value of 1. like this [1];
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (Number.isInteger(arr[i])) {
arr.splice(arr.indexOf(arr[i], 1));
}
}
Any one have an idea, if I'm doing it wrong or something. thanks for help.
You have a major problem, you are continually removing items from the array while looping through it. You have to go back one step (i--) every time an item is removed.
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (!isNaN(arr[i])) { // isNaN return true if it's not a valid number, so we have to inverse the test
arr.splice(i, 1); // if it's a valid number remove the element at the index i (no need to search for the index using indexOf, we already have it its i)
i--; // if we remove an element, we have to go back one step (or we will leave one item behind every time we remove another)
}
}
console.log(arr);
You could use typeof instead:
var arr = [1,2,3,'some','string'];
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'number') {
arr.splice(arr.indexOf(arr[i], 1));
}
}
The `.splice()' method makes changes to the array itself.
So for each iteration of the array, you are changing it fundamentally.
If you want the array to include only integers:
var arr = [1,2,3,'some','string'];
var newArray = [];
arr.forEach(function(element) {
if (Number.isInteger(element)){
newArray.push(element);
}
});
console.log(newArray);