How to square the second largest number in an array - javascript

I'm trying to find the 2nd largest number in an array, and square this number.
arr = [1,8,6,2,5,4,8,3,7] should return 49 (7 squared)
arr = [1,1] should return 1 (1 squared)
I've tried the code below and it works on the first array and return 49, but on the second array with [1,1] it returns NaN.
The problem is with the secondLargest variable--it returns undefined on the console.log. It may be because I'm using set, but I don't understand why it's not just returning 1 instead of undefined.
var maxArea = function(height) {
let secondLargest = Array.from([...new Set(height)]).sort((a,b) => b-a)[1]
console.log(secondLargest);
return Math.pow(secondLargest, 2);
};

Set eliminates duplicates, so the array [1, 1] gets turned into [1]. There is no second element, so you get undefined when trying to access index 1. Since this is not what you want, sort the array directly without creating a Set, or take the first element when there is no second element.
function maxArea(height) {
const sorted = [...new Set(height)].sort((a,b) => b-a);
return (sorted[1] ?? sorted[0]) ** 2;
}
console.log(maxArea([1, 1]));
console.log(maxArea([1,8,6,2,5,4,8,3,7]));

Related

How would you find the values in an array that equal the sum a specified number?

I'm working on creating a basic function that takes in 2 parameters -- array and num.
In the array are a list of numbers and the output could essentially generate 3 results:
0 with no two numbers that equal the sum equal to num.
1 variation of two numbers that is equal to the sum that is num
Multiple variations of 2 numbers that equal the sum that is num
I've been working with filter and reduce but haven't been able to produce the desired output.
Let's say I have a nums array of [3,6,9,18] and have a specified num value of 15.
var findNumSum = function(nums, num) {
function val(a, b) {
a + b === num;
var es = [a, b]
return es;
}
var result1 = nums.filter(val); // [3,6,9,18]
var result2 = nums.reduce(val); // [[6, 9], 18]] -- I've been able to isolate the num values but wasn't the result I was expecting. I'm still pretty fresh at this.
};
Let's assume you want to find sums for the number 6. Check the first number of the array, let it be 2. You now want to know if there's a 4 in you array, so you check that. Do this process for all the numbers in the array and remove duplicates.
Maybe this could help ?
Here is a little snippets along the lines of the previous suggestions:
const arr=[...Array(25)].map((_,v,)=>v), // create an array with 25 numbers
findsum=(ar,sum)=>
ar.reduce((a,c,i)=>
(c>sum || ar.slice(i+1).forEach(v=>
c+v-sum || a.push([c,v])),a)
,[] );
console.log(findsum(arr,27)) // find all possible pairs that add up to 27
Maybe it is helpful to you?
Only if the first condition c>sum is false the following ar.slice(i+1).forEach(...) will be executed. inside the forEach()-callback function the a.push([c,v]) will only be performed c+v-sum is "falsy" i. e. ==0.

Spinning the elements of an array clockwise in JS

I am supposed to rotate an array of integers clockwise in JS.
Here is my code for it:
function rotateArray(N, NArray)
{
//write your Logic here:
for(j=0;j<2;j++){
var temp=NArray[N-1];
for(i=0;i<N-1;i++){
NArray[i+1]=NArray[i];
}
NArray[0]=temp;
}
return NArray;
}
// INPUT [uncomment & modify if required]
var N = gets();
var NArray = new Array(N);
var temp = gets();
NArray = temp.split(' ').map(function(item) { return parseInt(item, 10);});
// OUTPUT [uncomment & modify if required]
console.log(rotateArray(N, NArray));
The code accepts an integer N which is the length of the array. The input is as follows:
4
1 2 3 4
The correct answer for this case is supposed to be
4 1 2 3
But my code returns
4 1 1 1
I cannot find where my code is going wrong. Please help me out.
All you need to do is move one item from the end of the array to the beginning. This is very simple to accomplish with .pop() (removes an item from the end of an array), then declare a new array with that element as the first:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem, ...NArray];
}
console.log(rotateArray(1, [1, 2, 3, 4]));
Doing anything else, like using nested loops, will make things more unnecessarily complicated (and buggy) than they need to be.
If you don't want to use spread syntax, you can use concat instead, to join the lastItem with the NArray:
function rotateArray(N, NArray) {
const lastItem = NArray.pop();
return [lastItem].concat(NArray);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
If you aren't allowed to use .pop, then look up the last element of the array by accessing the array's [length - 1] property, and take all elements before the last element with .slice (which creates a sub portion of the array from two indicies - here, from indicies 0 to the next-to-last element):
function rotateArray(N, NArray) {
const lastItem = NArray[NArray.length - 1];
const firstItems = NArray.slice(0, NArray.length - 1);
return [lastItem].concat(firstItems);
}
console.log(rotateArray(1, [1, 2, 3, 4]));
function rotate(array,n){
Math.abs(n)>array.length?n=n%array.length:n;
if(n<0){
n=Math.abs(n)
return array.slice(n,array.length).concat(array.slice(0,n));
}else{
return array.slice(n-1,array.length).concat(array.slice(0,n-1));
}
}
console.log(rotate([1, 2, 3, 4, 5],-3));
The answer by #CertainPerformance is great but there's a simpler way to achieve this. Just combine pop with unshift.
let a = [1,2,3,4];
a?.length && a.unshift(a.pop());
console.log(a);
You need to check the length first so you don't end up with [undefined] if you start with an empty array.

Shorter way to remove an item by index from an array [duplicate]

This question already has answers here:
How to delete an item from state array?
(18 answers)
Closed 5 years ago.
I've made this post last year and today, I assume things can be simplified.
I need to remove an item from an array but by the index. When by the index, it does not matter if the array has same values. Your typical example:
let arr = [1,2,3,2,1] // just an array, not array with objects
let x = 1;
// This will not be an expected result:
// Find all values that is equal to 1 then remove
arr.filter(num => num !== x) //=> [2,3,2]
My expectation is when I remove the last element (1), for example, the array should be [1,2,3,2]:
let index = 4; // which is the last "1" in the array
let indexVal = arr.indexOf(4) // 1
let newArray = arr.splice(indexVal, 1) //=> [1,2,3,2]
Now, it's 2017, almost '18, is there a shorter way (es5/6) of doing this without any polyfil?
Edit:
Think of this as a todo:
<ul>
<li>me</li>
<li>me</li> // click to delete this one
<li>you</li>
<li>me</li>
</ul>
To correctly remove that item, I have to delete by the index not value
The Array.filter callback gives 2 arguments, number and index and you can filter the array this way.
let arr = [1,2,3,2,1]
let x = 4; //suppose you want to remove element at 4th index
let editedArray = arr.filter((num, index) => index !== x) //editedArray = [1,2,3,2]
EDIT:
The third parameter gives the whole array. Thanks #Oliver for pointing this out in comment
arr.splice(index, 1);
or if you specifically want to remove the last element:
arr.pop();
No indexOf call. The indexOf call never should have been there; it only ever looked like it worked because indexOf returns -1 for an element that isn't present, and splice treats negative indices as counting from the end of the array.
Also, splice modifies the array in place and returns an array of removed elements, so assigning its return value the way you were doing is misleading.
The only way I can think of is the one we use in Redux every day:
const arr = [1, 2, 3, 2, 1]
const index = 4 // index of the item you want to remove
const newArr = [...arr.slice(0, index), ...arr.slice(index + 1)]
console.log(newArr) // [1, 2, 3, 2]
It might not be the shortest but it is more 2017 and it is immutable, which is very important!
Ajay's answer might be what you're looking for. Anyway, there are people like me who prefer slightly-more-lines-but-more-readable/rewritable/maintable solution, I'd do it this way:
function removeElementByIndex(arr, x) {
var newArr = [];
for(var i = 0; i < arr.length; i++) {
if(i != x) {
newArr.push(arr[i]);
}
}
return newArr;
}
// Usage
removeElementByIndex([1, 2, 3, 2, 1], 4);// outputs: [1, 2, 3, 2]
Now, it's 2017, almost '18, is there a shorter way (es5/6) of doing
this without any polyfil?
LOL! Many basic things not yet implemented. We'll have to wait for 2118 or another programming language to replace JS (oh wait, there's one, aka jQuery :P ).

How do I get the second largest element from an array in javascript

I have an integer array like this :
arr[20,120,111,215,54,78];
I need a function taking an array as its argument and returning the second largest element of that array.
The most straightforward implementation, without modifying the original array, is to iterate and track the biggest and next biggest:
function nextBiggest(arr) {
let max = -Infinity, result = -Infinity;
for (const value of arr) {
const nr = Number(value)
if (nr > max) {
[result, max] = [max, nr] // save previous max
} else if (nr < max && nr > result) {
result = nr; // new second biggest
}
}
return result;
}
const arr = ['20','120','111','215','54','78'];
console.log(nextBiggest(arr));
Variations
The behaviour of returning -Infinity if there's no next maximum value distinct from the maximum value in a non-empty array can be modified at the end of the function, depending on the requirements.
Same as maximum
return result == -Infinity ? max : result;
For an empty array, this will return -Infinity as before, but would otherwise return the same value as the maximum if no next distinct maximum is found.
Return null
return result == -Infinity ? null : result;
Same as above, but the return value of null is more indicative of the nonexistence of a next distinct maximum.
Original answer
var secondMax = function (){
var arr = [20, 120, 111, 215, 54, 78]; // use int arrays
var max = Math.max.apply(null, arr); // get the max of the array
arr.splice(arr.indexOf(max), 1); // remove max from the array
return Math.max.apply(null, arr); // get the 2nd max
};
demo
Update 1
As pointed out by davin the performance could be enhanced by not doing a splice but temporarily replacing the max value with -Infininty:
var secondMax = function (arr){
var max = Math.max.apply(null, arr), // get the max of the array
maxi = arr.indexOf(max);
arr[maxi] = -Infinity; // replace max in the array with -infinity
var secondMax = Math.max.apply(null, arr); // get the new max
arr[maxi] = max;
return secondMax;
};
Anyway, IMHO the best algorithm is Jack's. 1 pass, with conversion to number.
Mine is just short, using builtin methods and only wanted to provide it as an alternative, to show off all the different ways you can achieve the goal.
Update 2
Edge case with multiple values.
As comments pointed it out: this solution "does not work" if we have an array like [3, 3, 5, 5, 5, 4, 4].
On the other hand it would be also a matter of interpretation what we would consider "the 2nd largest element".
In the example we have:
3 elements with the largest value (5) at indices: 2,3,4
2 elements with the second largest value (4) at indices: 5,6
2 elements with the second smallest value (3) at indices: 1,2
The 2nd largest element could be interpreted as:
the 2nd (largest element) - 5 at index 3 - assuming that there is an order, and that we aim for a unique value
the (2nd largest) element - 4 at index 5 - assuming that there is an order, and that we aim for a unique value
The simplest solution is to sort :
// here's your array :
var stringArray = new Array('20','120','111','215','54','78');
// let's convert it to a real array of numbers, not of strings :
var intArray = stringArray.map(Number);
// now let's sort it and take the second element :
var second = intArray.sort(function(a,b){return b-a})[1];
If you don't want the simplest but the fastest (you probably don't need it), then you'd have to write your for loop and store the two greatest elements while looping.
First sort it backwards and then get the second element:
['20','120','111','215','54','78'].sort(function(a, b) { return b - a; })[1];
// '120'
Obviously works with strings too.
Sort the array and then return the second index.
var arr = ['20','120','111','215','54','78'];
arr.sort(function(a,b){
return b-a;
});
console.log(arr[1]);
You can try this:
function second_highest(arr)
{
var second_highest = arr.sort(function(a, b) { return b - a; })[1];
return second_highest;
}
Sort your array from smallest to largest, then grab second one from the end with .length-2
var myArray =['20','120','111','215','54','78'];
var secondLargest = myArray.sort(function(a,b){return a - b})[myArray.length-2];
alert(secondLargest); //120;
function getSecondLargest(nums) {
return [...new Set(nums)].sort((a,b)=>b-a)[1]
}

Getting nth smallest number location in array

Pretty basic question but I can't seem to find any examples of how to solve it in Javascript.
I would like to create a function where you pass a number representing "n" and it returns the location of the nth smallest number in the array.
For instance, if I did:
array = [5,6,1,1,1,8]
n = 3
location = nth_smallest(array, n)
Location would then be equal to 4, because the third lowest number is 1 however I would like to skip the first several duplicates of that number.
The common solution to finding the location of the nth smallest number is by doing:
array = [5,6,1,1,1,8]
n = 3
nth_lowest = array.slice(0).sort()[n]
location = $.inArray(nth_lowest, array)
However the problem is that it will always return the location being 2 because it knows that the third smallest number is 1 but the inArray function doesn't care about duplicates.
Is there any way to do this, possibly without using the sort function? It seems to take up a lot of processing and this is a function that will be run quite often.
// remap array as pairs of value and index
// e.g. change [5, 6, 1] to [[5, 0], [6, 1], [1, 2]]
var augmented_array = array.map(function(val, index) { return [val, index]; });
// sort pairs by the first position, breaking ties by the second
augmented_array.sort(function(a, b) {
var ret = a[0] - b[0];
if (ret == 0) ret = a[1] - b[1];
return ret;
});
// example array will now be [[1, 2], [5, 0], [6, 1]]
// so we get the location by just looking at the second position of a pair
var location = augmented_array[n - 1][1];
If you want the last location having that value, after the sort do:
var position = n - 1;
while (position < augmented_array.length - 1 &&
augmented_array[position][0] == augmented_array[position + 1][0]) {
++position;
}
var location = augmented_array[position][1];
Or if you want the first location, do:
var position = n - 1;
while (position > 0 &&
augmented_array[position][0] == augmented_array[position - 1][0]) {
--position;
}
var location = augmented_array[position][1];
Of course, lastIndexOf or indexOf, as suggested by one of the other answers would result in less code.
If I understand your question correctly, you are looking for the position of the last instance of the n-th lowest number? If so, try this:
array = [5,6,1,1,1,8];
n = 3;
nth_smallest = array.slice(0).sort()[n];
location = array.lastIndexOf(nth_smallest); // assumes non-ancient browser and/or shim
A haxy shim of lastIndexOf could be done like so:
function lastIndexOf(array,item) {
return array.join("\x00").match(new RegExp(".*\x00"+item+"\x00"))[0].split("\x00").length-1;
}
This shim would need calling like so: location = lastIndexOf(array,nth_smallest);
const arr = [9,3,4,5,3,4,6,7,8,];
arr.sort((a,b)=>{return a-b});
console.log(arr[arr.length-1]);
arr.sort((a,b)=>{return a-b});
console.log(arr[0]);
to find lowest number or highest number in array first you need to sort any array then array will be short sequence after the sort any array always in index (arr[0]) will be lowest number in any array and (arr[arr.lenght-1]) always highest number because we sort in sequnece
thanks...

Categories

Resources