I had to find maximum in array so I wrote a function which used for loop while also using ternary operator and I noticed that just reversing the direction of loop changes the output plus the output is also different if I use if-else. Moreover, changing the position of 'a' in the array also changes the output.
const array2 = ['a', 3, 4, 2];
function biggestNumberInArray(arr) {
let max=0;
for (let i = 0; i < arr.length; i++) {
max = max>arr[i]?max:arr[i];
}
return max;
}
function biggestNumberInArray2(arr) {
let max=0;
for (let i = arr.length - 1; i >= 0; i--) {
max = max>arr[i]?max:arr[i];
}
return max;
}
console.log(biggestNumberInArray(array2));
console.log(biggestNumberInArray2(array2));
When running the first function output is 4
When running the second function output is 'a'
If you step through the debugger and look at the comparisions ... you'll see that comparing 'a' with any number is always false.
That's why it seems to "work" in one direction, but not the other.
Specifically:
When comparing a string with a number, JavaScript will convert the
string to a number when doing the comparison. An empty string converts
to 0. A non-numeric string converts to NaN which is always false .
When comparing two strings, "2" will be greater than "12", because
(alphabetically) 1 is less than 2.
Because string 'a' and integers 2,3,4 are incomparable. Therefore it always returns false
In your first function, it returns 4 because 'a' is compared first and returns false, then max is assigned 3
In the second function it returns 'a' because 'a' is compared last.
You can check if the string can be converted to number using Number() or parseInt()
const arr = ['a', 3, 4, 2];
function biggestNumberInArray2(arr) {
let max=0;
for (let i = arr.length - 1; i >= 0; i--) {
const comparable = Number(arr[i]) || -99
max = max > comparable ? max : comparable;
}
return max;
}
console.log(biggestNumberInArray2(arr))
Related
So on LeetCode, I need to return the sum of two numbers that equal the target number. This is a leetcode "easy" type. I've never done leetcode before so I decided to give it a try. Right off the bat, I was able to solve the problem but my solution was nonsenical because it checks each number in the array against eachother. So if the input is a million digits then it will check it a million times for each number.
It's worth noting that although my program works, it can be submitted due to time limit exceeding.
I'm not sure what the mathematical solution would be to opitmize this. I'm currently going to Maths again learning what I am weak at.
Code:
var twoSum = function(nums, target) {
let total = [];
let inc = 1;
let intVal = 0;
let startingPos = nums[intVal];
let nextPos = nums[inc];
for(let x = 0; x < nums.length; x++){
// Do not check the value of position 1 with position 2
if(nums.indexOf(startingPos) === nums.lastIndexOf(nextPos)){
nextPos++;
}
if(startingPos + nextPos === target){
console.log(`First Value ${startingPos}`)
console.log(`Second Value ${nextPos}`)
console.log(`Target ${target}`)
// A match has been found
return [nums.indexOf(startingPos), nums.lastIndexOf(nextPos)];
} else{
// Move to next number if index 1 is not eql
// nextPos++;
let nextPosIndex = nums[inc];
nextPos = nums[inc];
console.log(`Values [${startingPos}], [${nextPos}]`)
console.log("No Matches");
// Increment the next value to check
inc++;
// Reset loop if no match is found from 2nd position
if(x == (nums.length - 1)){
// Increment the initial value in first pos
intVal++;
startingPos = nums[intVal];
// Reset values to check new numbers
x = 0;
inc = 1;
}
// check if we exhausted all options
if(startingPos === undefined){
return "No Matches.";
}
}
}
};
twoSum([5, 2, 5, 5, 1, 3, 6, 8, 4, 3, 2, 7], 14)
--
Before proceeding to any more problems, I am afraid I will be in this loop of choosing the most illogical way of solving the problems.
What can I do to modify this problem to quickly check if two values equals the target.
Here is a live compiler example: https://replit.com/#FPpl/SafeHeartfeltArchitect#index.js
When iterating over a number, you can put the value that, if it would match to sum to the target, into a collection (with O(1) lookup). For example, if you iterate over a number 5, and the target is 20, put 15 into the collection.
During an iteration, if the number being iterated over already exists in the collection, you have a match from one you found previously, and you can return both indicies.
const twoSum = function(nums, target) {
// For this Map, the key is the number which, if found again, is a match
// eg, if target is 20, and the number 5 is iterated over
// the key will be 15
// The value is the index of the prior number found - eg, index of 5
const valuesAlreadyFound = new Map();
for (let i = 0; i < nums.length; i++) {
const num = nums[i];
if (valuesAlreadyFound.has(num)) {
// We have a match, get both indicies:
console.log('Match for values', target - num, num);
return [valuesAlreadyFound.get(num), i];
}
// This wasn't a match. Identify the number which, when paired, is a match
const matchNeeded = target - num;
valuesAlreadyFound.set(matchNeeded, i);
}
return 'No match';
};
console.log('Indicies found:', twoSum([5, 2, 5, 5, 1, 3, 6, 8, 4, 3, 2, 7], 14));
const numbersArray = [5, 3, 1, 3, 4, 5, 3, 1];
var pastNumbers = [];
for (let i = 0; i < numbersArray.length; i++) {
const number = numbersArray[i];
pastNumbers.push(number);
var count = 0;
pastNumbers.forEach((v) => (v === number && count++));
console.log(`There are ${count} numbers before equal to ${number}. The last equal number is in the ${???} position.`);
}
I have an array called pastNumbers that stores the numbers that were previously traversed by the for loop of another array called numbersArray. Then with forEach I get the amount of previous numbers equal to number.
I want to know the position of the last number equal to number within the pastNumbers array.
How can I do it?
Updated with for loop
Use an object instead of array to track, it makes it a bit easier.
In this example, I'm going over each number and adding the position at the beginning (unshift) to pastNumber[number].
I'm using unshift so that the first item is the last position registred. That way I can look up with [0] instead of using [$.length-1] (but I'm still still using the length anyway so you push is fine too 🤷♂️)
const numbersArray = [5, 3, 1, 3, 4, 5, 3, 1];
const pastNumbers = {};
for (let i = 0; i < numbersArray.length; i++) {
const number = numbersArray[i];
if (!pastNumbers[number]) {
pastNumbers[number] = [];
}
if (pastNumbers[number].length > 0) {
console.log(
`There are ${pastNumbers[number].length} numbers before equal to ${number}. The last equal number is in the ${pastNumbers[number][0]} position.`
);
}
pastNumbers[number].unshift(i);
}
I'm looking to answer a coding challenge in JavaScript that I'm stuck on, here's the question:
Write a function which accepts an array of integers and returns an element of that array.
The function should determine the frequency of each element (how many times the element appears in the array) and whenever possible should return the element with the second-lowest frequency. Otherwise it should return the integer with the lowest frequency.
If there is more than one element satisfying the requirements then the second smallest one (according to value) should be returned.
Example outputs:
secondLowest( [4, 3, 1, 1, 2] ) === 1
secondLowest( [4, 3, 1, 1, 2, 2] ) === 2
secondLowest( [4, 3, 1, 2] ) === 2
This is what I've got so far although don't know how best to go about answering it after this:
function mode(array) {
if (array.length == 0) return null;
let modeMap = {};
let maxEl = array[0],
maxCount = 1;
for (let i = 0; i < array.length; i++) {
var el = array[i];
if (modeMap[el] == null) modeMap[el] = 1;
else modeMap[el]++;
if (modeMap[el] > maxCount) {
maxEl = el;
maxCount = modeMap[el];
}
}
return maxEl;
}
I was determined to give a generic, parameterized function, where no number is hardcoded.
Your example involved two hardcoded values:
The second least frequency should be selected
In cases of ties, the second least value should be selected
The following code works like this:
Get the frequency of each input value
Group together all values with the same frequency.
Sort these grouped pairs by frequency and select the nth-lowest (in your case, n=2)
If the nth-lowest frequency has multiple pairs, sort these pairs by value, and select the mth-lowest pair (in your case, m=2)
Return the value of this final pair
The m and n parameters I refer to here are called freqInd and valInd in the code. Note that in order to select the second-lowest frequency, freqInd should be 1, not 2 (since 0 would select the lowest, and therefore 1 selects the second-lowest).
let lowestFreqVal = (freqInd, valInd, values) => {
// Calculate frequencies in a map
let f = new Map();
for (let v of values) f.set(v, (f.get(v) || 0) + 1);
// Group together all val/freq pairs with the same frequency
let ff = new Map();
for (let [ val, freq ] of f) ff.set(freq, (ff.get(freq) || []).concat([ val ]));
// Sort these groups by frequency
let byFreq = [ ...ff ].sort(([ freq1 ], [ freq2 ]) => freq1 - freq2);
// Here are all the items of the `freqInd`-th lowest frequency, sorted by value
// Note that `[1]` returns an array of integers at the frequency, whereas `[0]` would return the frequency itself
let lowestItems = byFreq[ Math.min(byFreq.length - 1, freqInd) ][1]
.sort((v1, v2) => v1 - v2);
// Return the `valInd`-th lowest value
return lowestItems[ Math.min(lowestItems.length - 1, valInd) ];
};
console.log('Some random examples:');
for (let i = 0; i < 10; i++) {
// An array of random length, full of random integers
let arr = [ ...new Array(3 + Math.floor(Math.random() * 5)) ]
.map(v => Math.floor(Math.random() * 4));
// Show the result of `lowestFreqVal` on this random Array
console.log(`lowestFreqVal(1, 1, ${JSON.stringify(arr)}) = ${lowestFreqVal(1, 1, arr)}`);
}
This is not an optimal solution, since it resorts to using sort. It's known that the problem of finding some nth-maximal value in a list can be implemented to have a better runtime than sort (and a significantly better runtime when n is a small value - we can see this intuitively because if n=0, a single pass (O(n)) does the trick).
Is there a way to compare an integer against an array of integers? For instance, to determine if an int is larger than any of the array ints?
var array = [1, 2, 3, 4];
if(5 > array){
// do something
}
Update: I guess I meant, is 5 larger than the largest number in the array. Thanks!
You can use Math.max and apply
if (5 > Math.max.apply(Math, array)) {
// do something
}
Update: To explain as it works. It's described in the docs I linked but I will try to be more clear here:
Math.max returns the largest of zero or more numbers, so:
Math.max(1, 2, 3, 4) // returns 4
apply calls a function with a given 'this' value (the first argument) and arguments provided as an array (the second). so:
function sum(a, b) {
return a + b;
}
console.log(sum.apply(window, [2, 3])); // 5
Therefore, if you have an array of integers and you want to get the max, you can combine them to have:
console.log(Math.max.apply(Math, [1, 2, 3, 4])); // 4
Because it's exactly like have:
console.log(Math.max(1, 2, 3, 4));
The difference is you pass an array instead.
Hope it's more clear now!
There is no good and readable built in way of doing it, but it can be done simply with:
var bigger = true;
for (var i =0; i < array.length; i++) {
if (5 <= array[i]) {
bigger = false;
// you can add here : break;
}
}
Sure, you could sort the array, take the last element, and see if your integer is greater than that. Or, you could loop through and check each one. Up to you. The loop is a more performant way.
//maybe check the bounds on this if you know it can be a blank array ever
var max = myArray[0];
for(var x = 0; x < myArray.length; x++) {
max = Math.max(max, myArray[x]);
}
if(500 > max) {
//do something
}
I need a piece of code that basically lets me specify the length of the array (y) and the highest index point (x), and returns an array where the index of x is equal to y.
For instance:
y = 7
x = 3
0, 1, 7, 2, 3, 4, 5, 6
Ultimately this is producing a list of numbers from 0 to 7, and then rearranging those numbers so that the largest number is 3rd in the list.
var y = 7,
x = 3,
arr = [];
for (var i = 0; i < y + 1; i++) {
arr[i] = i;
}
arr.splice(x - 1, 0, arr.pop());
arr; // 0,1,7,2,3,4,5,6
jsFiddle.
You can create an array easily using the [] syntax:
[] // An empty array
You can add items to an array using push:
myArray.push(someValue);
So, how could you create an array from 0 to y, using a for loop? If you can't figure it out, mouse over the below rectangle:
var arr = [];for(var i = 0; i <= y; i++) { arr.push(i);}
Okay, you have your array, now all you need to do is move the last element to the xth position. You can do this using the very versatile Array.splice, check out the documentation.
Now check your answer:
arr.splice(x, 0, arr.pop());
arr is now the result you needed.
jsFiddle.
Here is yet another (and understandable, albeit a bit lengthier than others' answers):
var x = 3,
y = 7;
arr = [];
for(var i=0;i<y+1;i++){
if(i == x - 1){
arr[i] = y;
} else if(i >= x){
arr[i] = i - 1;
} else {
arr[i] = i;
}
}
Example.
During the for loop, when i is equal to x - 1 (Javascript has 0-based indexing), it will set arr[i] equal to y. If i is greater than or equal to x, it will set arr[i] to i - 1 (so we're subtracting 1 from each value of the array after the one we set to y). The last else covers the array's values before we get stuff complicated (so 0 and 1).
I need a piece of code that basically lets me specify the length of the array (y) and the highest index point (x), and returns an array where the index of x is equal to y.
The length of the array is not y, it is y+1 if you want the first element to have the value 0. Note also that JavaScript array indexes are 0-based, so the third array position has index 2, or x-1.
The following matches your sample input/output of 7,3 => 0,1,7,2,3,4,5,6
function makeStrangeArray(y, x) {
var a = [],
i;
for(i = 0; i < y; i++) {
if(i===x-1)
a.push(y);
a.push(i);
}
return a;
}
alert(makeStrangeArray(7,3)); // 0,1,7,2,3,4,5,6