How to Make Consecutive Numbers from an Array - javascript

I have an array like this
[-2,4,5,6,7,8,10,11,15,16,17,18,21]
Is anyone know, how to make the output from that array become integer like this
-2,4-8,10-11,15-18,21
The output will take the consecutive number become one number
This things is new for me, any help would be appreciated, thanks

Below I created function for replacing a sequence in an array with a string containing its range. There are three functions.
getConsectiveCount will take array and index as arguments and will get the count of consecutive numbers after that.
replaceFirstConsective will take array and will replace only first sequence in the array.
replaceAllConsectives will replace all the sequences in an array.
const arr = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
const getConsectiveCount = (arr, index) => {
let count = 0;
for(let i = index; i < arr.length; i++){
if(arr[i + 1] === arr[index] + (i - index) + 1){
count++;
}
}
return count;
}
console.log(getConsectiveCount(arr, 1));
const replaceFirstConsective = (arr) => {
for(let i = 0; i < arr.length; i++){
let count = getConsectiveCount(arr,i);
if(count){
return [...arr.slice(0, i), `${arr[i]}-${arr[i + count]}`, ...arr.slice(i + count + 1)]
}
}
return arr;
}
const replaceAllConsectives = (arr) => {
for(let i = 0; i < arr.length;i++){
arr = replaceFirstConsective(arr)
}
return arr;
}
console.log(JSON.stringify(replaceAllConsectives(arr)))

const inp = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
let res = [];
for(let i=0;i<inp.length;i++){
let b = inp[i];
let j = i+1;
while(j<inp.length){
if(b+1 == inp[j]){
b = inp[j++];
continue;
}
break;
}
if(i == j-1){
res.push(inp[i]);
}
else{
res.push(inp[i]+"-"+inp[j-1]);
i=j-1;
}
}
console.log(res);
Check this if it helps.

I have done that :
const arr1 = [-2,4,5,6,7,8,10,11,15,16,17,18,21]
const arr2 = arr1.reduce((a,c,i,{[i+1]:nxt})=>
{
if (!a.s1) a.s1 = c.toString(10)
if ( (c+1) !== nxt )
{
a.s1 += a.s2 ? `_${a.s2}` : ''
a.r.push(a.s1)
a.s1 = a.s2 = ''
}
else a.s2 = nxt.toString(10)
return (nxt===undefined) ? a.r : a
},{r:[],s1:'',s2:''})
console.log(JSON.stringify( arr2 ))
.as-console-wrapper { max-height: 100% !important; top: 0; }

It's an interesting problem. The way I solved it was to iterate over the array and then find the index of the last consecutive number from the current one. We can either write the single number into the result array or write the range string in there and continue from the next number after the range.
function lastConsecutive(arr, start)
{
let ind = start;
while(ind < arr.length && (arr[ind] + 1) == arr[ind + 1])
{
ind++;
}
return ind;
}
function consecCollapse(nums)
{
let i = 0;
const result = [];
while (i < nums.length)
{
let n = lastConsecutive(nums, i);
result.push((n == i) ? nums[n]+"" : nums[i]+"-"+nums[n]);
i = n + 1;
}
return result;
}
console.log(consecCollapse([-2,4,5,6,7,8,10,11,15,16,17,18,21]));

const arr = [-2,4,5,6,7,8,10,11,15,16,17,18,21];
const _newArray = [];
let start = arr[0];
let end = start;
for(let i=1; i<=arr.length; i++) {
let elem = arr[i];
if (elem === end+1) {
end = elem; // update the end value (range)
}else {
if (end !== start) {
_newArray.push(`${start}-${end}`);
} else {
_newArray.push(start);
}
start = elem;
end = start;
}
}
console.log(_newArray.join(','))

If a sorted array with unique numbers, this is how I find the range of numbers with dash:
function findRange(arr) {
const results = []
for (let i = 0; i < arr.length; i++) {
// only more than 2 consecutive numbers can be form a range
if (arr[i + 1] === arr[i] + 1 && arr[i + 2] === arr[i] + 2) {
// store the first number of a range
results.push(arr[i])
// loop until meet the next one is not consecutive
while (arr[i] + 1 === arr[i + 1]) {
i++
}
// store the last number of a range with '-' in between
results[results.length - 1] = results[results.length - 1] + '-' + arr[i]
} else {
// if only 2 consecutive number or not consecutive at all
results.push(arr[i])
}
}
return results
}
console.log(findRange([1, 2, 3, 4, 6, 7, 8, 9]))
console.log(findRange([1, 2, 4, 6, 7, 8, 9]))
console.log(findRange([-2,4,5,6,7,8,10,11,15,16,17,18,21]))

Related

triangle Number pattern using loop in javasctipt

Hello I'm having a problem.
I want to create a triangular number pattern as follows:
Output:
1223334444333221
=22333444433322=
===3334444333===
======4444======
I've tried to make the program. But the logic I use is not quite right.
function nomor4(level) {
let len = null;
let result = [];
while (level > 0) {
let arr = [];
for (let i = 1; i < level; i++) {
for (let repeat = 0; repeat <i; repeat++){
arr.push(i)
}
}
// convert arr.push value from array to string using join
//and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "-" + str_level + "-";
}
result.push(str_level);
level--;
}
return result.join("\n");
}
console.log(nomor4(4))
if anyone can. please help me give the solution. Thank you
Here's a way of doing this by using two nested maps over arrays of rows (a counter for each row) and columns (the values to print in each row)
const size = 4
const fill = '='
const rows = Array.from({length: size}, (_, i) => i + 1) // 1,2,3,4
const cols = rows.concat(rows.slice(0, -1).reverse()) // 1,2,3,4,3,2,1
const result = rows
.map(r => cols
.map(c => ((c >= r) ? c : fill).toString().repeat(c)
).join('')
).join('\n')
console.log(result)
There are better ways than this, but I will put this here just to show how to do it with minimal changes from the OP (I just changed - to = and the for loop with i).
function nomor4(level) {
let len = null;
let result = [];
while (level > 0) {
let arr = [];
for (let i = 5-level; i < 4; i++) {
for (let repeat = 0; repeat <i; repeat++){
arr.push(i)
}
}
// convert arr.push value from array to string using join
//and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "=" + str_level + "=";
}
result.push(str_level);
level--;
}
return result.join("\n");
}
console.log(nomor4(4))
function nomor4(level) {
let realValue = level;
let len = null;
let result = [];
while (level >= 0) {
let arr = [];
for (let i = 1; i <= realValue; i++) {
if (realValue !== i) {
for (let repeat = 0; repeat < i; repeat++) {
if (realValue - level <= i) {
arr.push(i);
}
}
}
}
// convert arr.push value from array to string using join
// and add 1 and the copy value using reverse
let str_level = arr.join("") + "4444" + arr.reverse().join("");
if (len == null) {
len = str_level.length;
}
//Add Strip
while (str_level.length < len) {
str_level = "-" + str_level + "-";
}
result.push(str_level);
result = [...new Set(result)];
level--;
}
return result.join("\n");
}
console.log(nomor4(4));

best way to find two number in an array which their sum be a specific number

what is the best algorithm to find two numbers in an array which their sum be a specific number ? for example Array = [1,5,73,68,2] and specific number is 70 . output must be 68 + 2 = 70
so if you want a better solution with better time complexity you can reach O(n) instead of O(n^2) and iterating the array only once.
but you need a data structure that has O(1) for finding data, something like hashmap.
and code would be like this:
function find(array, sum){
let answer = {}
for(const num of array){
if(answer[num]){
return { first: sum - num, second: num}
}
answer[sum - num] = true
}
return false
}
let arr = [ 2, 5, 7, 3, 82]
console.log(find( arr, 10))
I do my try, hope this helps.
function getPairs(arr, n, sum)
{ let temp = []
for (let i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
if (arr[i] + arr[j] == sum)
temp.push([arr[i],arr[j]])
return temp
}
let arr = [1,2,3,4]
console.log(getPairs(arr, arr.length, 3))
You can use a for loop
sums=[]
function findinarray(specialnumb){
array = [1,5,73,68,2]
for(let i=0;i<array.length;i++){
for(let j=1+i;j<array.length;j++){
o=array[i]
b=array[j]
if(o+b==specialnumb)
sums.push(o,b)
}
}
return sums
}
console.log(findinarray(70))
function example(){
var numbersArray = ['1','5','73','68','2'];
var number = 70;
for (let i = 0; i < numbersArray.length; i++) {
for (let j = 0; j < numbersArray.length; j++) {
if(Number(numbersArray[i])+Number(numbersArray[j]) == number){
console.log('found this:'+numbersArray[i]+'+'+numbersArray[j] +'='+number)
}
}
}
}
example();
Ofcourse you dont have to use console.log , this is just an example.
A simple example , i'm pretty sure there are another ways to do it.
I hope this will help you
Here you go: Working solution. Just run snippet to see in action.
You can pass array() to this function and total number you want to count in that array. In return it will console.log the indexes totaling that number which you wanted.
function checkSum(arrayValues, total) {
var map = [];
var indexxxx = [];
for (var x = 0; x < arrayValues.length; x++) {
if (map[arrayValues[x]] != null) {
var index = map[arrayValues[x]];
indexxxx[0] = index;
indexxxx[1] = x;
break;
} else {
map[total - arrayValues[x]] = x;
}
}
console.log('Array Index at ' + indexxxx[0] + ' & ' + indexxxx[1] + ' sums equals to ' + total)
}
checkSum([1, 5, 73, 68, 2], 70)
If you want to know the exact value totalling the number then you do this:
function checkSum(arrayValues, total) {
var indexxxx = [];
for (var x = 0; x < arrayValues.length; x++) {
for (var j = 1 + x; j < arrayValues.length; j++) {
o = arrayValues[x]
b = arrayValues[j]
if (o + b == total)
indexxxx.push(o, b)
}
}
console.log('Array value at ' + indexxxx[0] + ' & ' + indexxxx[1] + ' sums equals to ' + total)
}
checkSum([1, 5, 73, 68, 2], 70)
I just created this utility in order to find the pairs whose sum will be equal to the provided/expected sum. Here I have not used nested loops. This will also eliminate duplicate pairs.
getPairs = (array, sum) => {
const obj = {}
const finalResult = []
array.forEach(d => {
obj[sum - d] = d
})
Object.keys(obj).forEach(key => {
if (obj[sum - key]) {
finalResult.push([parseInt(key), sum - key])
delete obj[key]
}
})
return finalResult
}
const array = [1, 5, 73, 68, 2, 4, 74]
const sum = 78
console.log(getPairs(array, sum))
Hope this helps.

JavaScript find longest Uniform Substring

Trying to find longest Uniform Substring.
Suppose I have abbbccda then it should return [1, 3]. Because it starts from index 1 and is 3 characters long.
Other Example:
"10000111" => [ 1, 4 ]
"aabbbbbCdAA" => [ 2, 5 ]
I tried:
function longestUniformSubstring(input){
if(input){
let arr = input.split("");
let obj = {};
arr.map((ele, index) => {
return obj[ele] ? obj[ele][1]++ : obj[ele] = [index,1];
});
console.log(obj);
return obj;
}
else {
return [ -1, 0 ];
}
}
longestUniformSubstring("abbbccda");
It gives me object of all character But, no idea how can i get with highest length.
You could iterate the string and check the previous character and continue if the caracters are equal.
If not, check the length and assign a new logest array, if necessary and check if a longer string is not possible, then break the loop.
Assign the new found character and set a new start value to the actual index.
function longestUniformSubstring(input) {
var longest = [-1, 0],
start = 0,
character = input[0];
for (let i = 1; i <= input.length; i++) {
if (input[i] === character) continue;
if (longest[1] < i - start) {
longest = [start, i - start];
if (i + i - start >= input.length) break;
}
character = input[i];
start = i;
}
return longest;
}
console.log(...longestUniformSubstring("aabbbbbCdAA"));
console.log(...longestUniformSubstring("ab"));
console.log(...longestUniformSubstring("aa"));
console.log(...longestUniformSubstring(""));
You can keep track of the character being evaluated. When it changes, check to see if its repetition is larger than previous repetitions. If so, store the new version and move on.
function longestUniformSubstring(input){
const result = [-1, 0];
let currentCharacter = '';
let currentIndex = -1;
let currentCount = 0;
(input || '').split('').forEach((character, index) => {
if (character == currentCharacter) {
currentCount++;
} else {
if (currentCount > result[1]) {
result[0] = currentIndex;
result[1] = currentCount;
}
currentCharacter = character;
currentIndex = index;
currentCount = 1;
}
});
if (currentCount > result[1]) {
result[0] = currentIndex;
result[1] = currentCount;
}
return result;
}
console.log(longestUniformSubstring("abbbccdddda"));
You can write the logic like this, this works at my end.
function longestUniformSubstring(input) {
let length = input.length;
let firstLetter = input[0];
let sIndex = 0;
let eIndex = 0;
let resultIndex = 0;
let resultLength = 0;
while(sIndex < length && eIndex < length) {
if (input[eIndex] === firstLetter) {
eIndex++;
if (eIndex - sIndex > resultLength) {
resultLength = eIndex - sIndex;
resultIndex = sIndex;
}
}
else {
sIndex++;
if (input[sIndex] !== firstLetter)
{
firstLetter = input[sIndex];
}
}
}
return [resultIndex, resultLength];
}
console.log(longestUniformSubstring('AABBBBBCC'));
You can create a queue, to keep track of elements. and pop once all the iteration has been done.
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
let queue = [];
const map = {};
for (let index = 0; index < input.length; index++) {
const char = input[index];
if (!map[char]) map[char] = [index, 1];
else {
map[char][1] += 1;
}
const max = queue[0];
if (max && max[1] < map[char][1]) {
queue.unshift(map[char]);
} else {
queue.push(map[char]);
}
}
return queue.shift();
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
The dirty one, keep track of longest
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
let max = ["", -1, 0];
let map = {}
for (let index = 0; index < input.length; index++) {
const char = input[index];
if (!map[char]) map[char] = [index, 1];
else {
map[char][1] += 1;
}
if (max[2] < map[char][1]) {
max = [char, map[char][0], map[char][1]];
}
}
return [max[1], max[2]];
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
You can use .reduce to count. .sort method to get the min or max.
function longestUniformSubstring(input) {
if (!input) return [-1, 0];
const map = input.split("").reduce((m, item, index) => {
if (!m[item]) m[item] = [index, 1];
else {
m[item][1] += 1;
}
return m;
}, {});
return Object.values(map).sort(([_, i], [__, j]) => j - i)[0];
}
console.log(longestUniformSubstring("abbbccda"));
console.log(longestUniformSubstring("10000111"));
console.log(longestUniformSubstring("aabbbbbCdAA"));
You can just iterate over
function longestUniformSubstring(input){
if(!input) {
return [-1, 0];
}
let lastIndex=0;
let lastLength=1;
let currIndex=0;
let currLength=0;
for (let i = 1; i < input.length; i++) {
if(input.charAt(i)===input.charAt(i-1)) {
currLength++;
} else {
if (currLength > lastLength) {
lastIndex = currIndex;
lastLength = currLength;
}
currIndex = i;
currLength = 1;
}
}
return [lastIndex, lastLength];
}

Fibonacci series in JavaScript

function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = (i - 1);
const b = (i - 2);
result.push(a + b);
}
return result[n];
}
console.log(fib(8));
The output of the code above is 13. I don't understand the for loop part. In very first iteration i = 2, but after second iteration i = 3 so a = 2 and b = 1 and third iteration i = 4 so a = 3, b = 2, and so on... If it's going on final sequence will be :
[0, 1, 1, 3, 5, 7, 9, 11], which is incorrect. The correct sequence will be [0, 1, 1, 2, 3, 5, 8, 13]
You were not using the previous two numbers that are already in the array to > generate the new fibonacci number to be inserted into the array.
https://www.mathsisfun.com/numbers/fibonacci-sequence.html
Here I have used the sum of result[i-2] and result[i-1] to generate the new fibonacci number and pushed it into the array.
Also to generate n number of terms you need the condition to be i < n and not i <= n.
function fib(n) {
const result = [0, 1];
for (var i = 2; i < n; i++) {
result.push(result[i-2] + result[i-1]);
}
return result; // or result[n-1] if you want to get the nth term
}
console.log(fib(8));
Return result[n-1] if you want to get the nth term.
My solution for Fibonacci series:
const fibonacci = n =>
[...Array(n)].reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
[]
)
This function is incorrect. It cat be checked by just adding the console.log call just before the function return:
function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = (i - 1);
const b = (i - 2);
result.push(a + b);
}
console.log(result);
return result[n];
}
console.log(fib(7));
As you can see, the sequence is wrong and (for n = 7) the return value is too.
The possible change would be as following:
function fib(n) {
const result = [0, 1];
for (var i = 2; i <= n; i++) {
const a = result[i - 1];
const b = result[i - 2];
result.push(a + b);
}
console.log(result);
return result[n];
}
console.log(fib(8));
This is the "classical" Fibonacci numbers; if you really want to use the first number of 0, not 1, then you should return result[n-1], since array indexes start from zero.
One approach you could take for fibonacci sequence is recursion:
var fibonacci = {
getSequenceNumber: function(n) {
//base case to end recursive calls
if (n === 0 || n === 1) {
return this.cache[n];
}
//if we already have it in the cache, use it
if (this.cache[n]) {
return this.cache[n];
}
//calculate and store in the cache for future use
else {
//since the function calls itself it's called 'recursive'
this.cache[n] = this.getSequenceNumber(n - 2) + this.getSequenceNumber(n - 1);
}
return this.cache[n];
},
cache: {
0: 0,
1: 1
}
}
//find the 7th number in the fibbonacci function
console.log(fibonacci.getSequenceNumber(7));
//see all the values we cached (preventing extra work)
console.log(fibonacci.cache);
//if you want to output the entire sequence as an array:
console.log(Object.values(fibonacci.cache));
The code above is also an example of a dynamic programming approach. You can see that I am storing each result in a cache object the first time it is calculated by the getSequenceNumber method. This way, the second time that getSequenceNumber is asked to find a given input, it doesn't have to do any actual work - just grab the value from cache and return it! This is an optimization technique that can be applied to functions like this where you may have to find the value of a particular input multiple times.
const fib = n => {
const array = Array(n);
for (i = 0; i < array.length; i++) {
if (i > 1) {
array[i] = array[i - 1] + array[i - 2];
} else {
array[i] = 1;
}
}
return array;
}
console.log(fib(5))
What you are doing wrong is adding the iterator index (i), whereas what you need to do is add the element in the result at that index.
function fib(n) {
const result = [0, 1];
for (let i = 2; i <= n; i++) {
const a = result[(i - 1)];
const b = result[(i - 2)];
result.push(a + b);
}
console.log("Result Array: " + result);
return result[n];
}
console.log("Fibonacci Series element at 8: " + fib(8));
There are two issues with the logic:
Variables a and b currently refer to i - 1 and i - 2. Instead they should refer to the elements of result array, i.e. result[i - 1] and result[i - 2].
If you need 8th element of the array, you need to call result[7]. So the returned value should be result[n - 1] instead of result[n].
function fib(n) {
const result = [0, 1];
for (var i = 2; i < n; i++) {
const a = result[i - 1];
const b = result[i - 2];
result.push(a + b);
}
console.log(result);
return result[n - 1];
}
console.log(fib(8));
simple solution for Fibonacci series:
function fib(n){
var arr = [];
for(var i = 0; i <n; i++ ){
if(i == 0 || i == 1){
arr.push(i);
} else {
var a = arr[i - 1];
var b = arr[i - 2];
arr.push(a + b);
}
}
return arr
}
console.log(fib(8))
This is certainly one of those "more than one way to clean chicken" type situations, this JavaScript method below works for me.
function fibCalc(n) {
var myArr = [];
for (var i = 0; i < n; i++) {
if(i < 2) {
myArr.push(i);
} else {
myArr.push(myArr[i-2] + myArr[i-1]);
}
}
return myArr;
}
fibCalc(8);
When called as above, this produces [0,1,1,2,3,5,8,13]
It allows me to have a sequence of fib numbers based on n.
function fib(n) {
const result = [0];
if (n > 1) {
result.push(1);
for (var i = 2; i < n; i++) {
const a = result[result.length - 1]
const b = result[result.length - 2];
result.push(a + b);
}
}
console.log(result);
}
i came up with this solution to get the n index fibonacci value.
function findFac(n){
if (n===1)
{
return [0, 1];
}
else
{
var s = findFac(n - 1);
s.push(s[s.length - 1] + s[s.length - 2]);
return s;
}
}
function findFac0(n){
var vv1 = findFac(n);
return vv1[n-1];
}
console.log(findFac0(10));
Here, you have it, with few argument check, without using exception handling
function fibonacci(limit){
if(typeof limit != "number"){return "Please enter a natural number";}
if(limit <=0){
return "limit should be at least 1";
}
else if(limit == 1){
return [0];
}
else{
var series = [0, 1];
for(var num=1; num<=limit-2; num++){
series.push(series[series.length-1]+series[series.length-2]);
}
return series;
}
}
I came up with this solution.
function fibonacci(n) {
if (n == 0) {
return [0];
}
if ( n == 1) {
return [0, 1];
} else {
let fibo = fibonacci(n-1);
let nextElement = fibo [n-1] + fibo [n-2];
fibo.push(nextElement);
return fibo;
}
}
console.log(fibonacci(10));
function fibonacciGenerator (n) {
var output = [];
if(n===1){
output=[0];
}else if(n===2){
output=[0,1];
}else{
output=[0,1];
for(var i=2; i<n; i++){
output.push(output[output.length-2] + output[output.length-1]);
}
}
return output;
}
output = fibonacciGenerator();
console.log(output);
function fibonacci(end) {
if (isNaN(end) === false && typeof (end) === "number") {
var one = 0, res, two = 1;
for (var i = 0; i < end; ++i) {
res = one + two;
one = two;
two = res;
console.log(res);
}
} else {
console.error("One of the parameters is not correct!")
}
}
fibonacci(5);
var input = parseInt(prompt(""));
var a =0;
var b=1;
var x;
for(i=0;i<=input;i++){
document.write(a+"<br>")
x = a+b;
a =b;
b= x;
}

Find the second largest number in array

I have an array of three element like [31,23,12] and I want to find the second largest element and its related position without rearranging the array.
Example :
array = [21,23,34]
Second_largest = 23;
Position is = 1;
Make a clone of your original array using .slice(0) like :
var temp_arr = arr.slice(0);
Then sor it so you get the second largest value at the index temp_arr.length - 2 of your array :
temp_arr.sort()[temp_arr.length - 2]
Now you could use indexOf() function to get the index of this value retrieved like :
arr.indexOf(second_largest_value);
var arr = [23, 21, 34, 34];
var temp_arr = [...new Set(arr)].slice(0); //clone array
var second_largest_value = temp_arr.sort()[temp_arr.length - 2];
var index_of_largest_value = arr.indexOf(second_largest_value);
console.log(second_largest_value);
console.log(index_of_largest_value);
Using ES6 Set and Array.from
const secondLargest = (arr) => Array.from([...new Set(arr)]).sort((a,b) => b-a)[1]
Above function removes duplicate elements using Set and returns the second largest element from the sorted array.
I tried to make the answer as simple as possible here, you can it super simple
function getSecondLargest(nums) {
var flarge = 0;
var slarge = 0;
for (var i = 0; i < nums.length; i++) {
if (flarge < nums[i]) {
slarge = flarge;
flarge = nums[i];
} else if (nums[i] > slarge) {
slarge = nums[i]
}
}
return slarge;
}
Its fully logical ,there is no array sort or reverse here, you can also use this when values are duplicate in aray.
function getSecondLargest(nums) {
nums.sort(function(x,y){
return y-x;
});
for(var j=1; j < nums.length; j++)
{
if(nums[j-1] !== nums[j])
{
return nums[j];
}
}
}
getSecondLargest([1,2,3,4,5,5]);
OUTPUT: 4
This method will also take care of the multiple occurrence of a number in the array. Here, we are first sorting the array and then ignoring the same number and returning our answer.
You could create a copy of the original array using spread and sort() it. From you'd just get the second to last number from the array and use indexOf to reveal it's index.
const array = [21,23,34];
const arrayCopy = [...array];
const secondLargestNum = arrayCopy.sort()[arrayCopy.length - 2]
console.log(array.indexOf(secondLargestNum));
Alternatively you can use concat to copy the array if compatibility is an issue:
var array = [21, 23, 34];
var arrayCopy = [].concat(array);
var secondLargestNum = arrayCopy.sort()[arrayCopy.length - 2]
console.log(array.indexOf(secondLargestNum));
This way is the most verbose, but also the most algorithmically efficient. It only requires 1 pass through the original array, does not require copying the array, nor sorting. It is also ES5 compliant, since you were asking about supportability.
var array = [21,23,34];
var res = array.reduce(function (results, curr, index) {
if (index === 0) {
results.largest = curr;
results.secondLargest = curr;
results.indexOfSecondLargest = 0;
results.indexOfLargest = 0;
}
else if (curr > results.secondLargest && curr <= results.largest) {
results.secondLargest = curr;
results.indexOfSecondLargest = index;
}
else if (curr > results.largest) {
results.secondLargest = results.largest;
results.largest = curr;
results.indexOfSecondLargest = results.indexOfLargest;
results.indexOfLargest = index;
}
return results;
}, {largest: -Infinity, secondLargest: -Infinity, indexOfLargest: -1, indexOfSecondLargest: -1});
console.log("Second Largest: ", res.secondLargest);
console.log("Index of Second Largest: ", res.indexOfSecondLargest);
I recently came across this problem, but wasn't allowed to use looping. I managed to get it working using recursion and since no one else suggested that possibility, I decided to post it here. :-)
let input = [29, 75, 12, 89, 103, 65, 100, 78, 115, 102, 55, 214]
const secondLargest = (arr, first = -Infinity, second = -Infinity, firstPos = -1, secondPos = -1, idx = 0) => {
arr = first === -Infinity ? [...arr] : arr;
const el = arr.shift();
if (!el) return { second, secondPos }
if (el > first) {
second = first;
secondPos = firstPos;
first = el;
firstPos = idx;
} if (el < first && el > second) {
second = el;
secondPos = idx;
}
return secondLargest(arr, first, second, firstPos, secondPos, ++idx);
}
console.log(secondLargest(input));
// {
// second: 115,
// secondPos: 8
// }
Hope this helps someone in my shoes some day.
Simple recursive function to find the n-largest number without permutating any array:
EDIT: Also works in case of multiple equal large numbers.
let array = [11,23,34];
let secondlargest = Max(array, 2);
let index = array.indexOf(secondlargest);
console.log("Number:", secondlargest ,"at position", index);
function Max(arr, nth = 1, max = Infinity) {
let large = -Infinity;
for(e of arr) {
if(e > large && e < max ) {
large = e;
} else if (max == large) {
nth++;
}
}
if(nth==0) return max;
return Max(arr, nth-1, large);
}
Just to get 2nd largest number-
arr = [21,23,34];
secondLargest = arr.slice(0).sort(function(a,b){return b-a})[1];
To get 2nd largest number with index in traditional manner-
arr = [20,120,111,215,54,78];
max = -Infinity;
max2 = -Infinity;
indexMax = -Infinity;
index2 = -Infinity;
for(let i=0; i<arr.length; i++) {
if(max < arr[i]) {
index2 = indexMax;
indexMax = i;
max2 = max;
max = arr[i];
} else if(max2 < arr[i]) {
index2 = i;
max2 = arr[i];
}
}
console.log(`index: ${index2} and max2: ${max2}`);
I have tried to solve without using the inbuilt function.
var arr = [1,2, -3, 15, 77, 12, 55];
var highest = 0, secondHighest = 0;
// OR var highest = arr[0], secondHighest = arr[0];
for(var i=0; i<arr.length; i++){
if(arr[i] > highest){
secondHighest = highest;
highest = arr[i];
}
if(arr[i] < highest && arr[i] > secondHighest){
secondHighest = arr[i];
}
}
console.log('>> highest number : ',highest); // 77
console.log('>> secondHighest number : ',secondHighest); // 55
var arr = [21,23,34];
var output = getSecondLargest(arr);
document.getElementById("output").innerHTML = output;
function getSecondLargest(nums) {
if (nums.length == 0){
return undefined;
}
nums.sort((a,b) => b-a);
var newArr = [...new Set(nums)];
return newArr[1];
}
<p id="output"></p>
function getSecondLargest(nums) {
const sortedArray = new Set(nums.sort((a, b) => b - a)).values();
sortedArray.next();
return sortedArray.next().value;
}
console.log(getSecondLargest([1, 2, 4, 4, 3]));
//Suggest making unique array before checking largest value in the array
function getSecondLargest(arr) {
let uniqueChars = [...new Set(arr)];
let val=Math.max(...uniqueChars);
let arr1 = arr.filter(function(item) {
return item !== val;
})
let num=Math.max(...arr1);
return num;
}
function main() {
const n = +(readLine());
const nums = readLine().split(' ').map(Number);
console.log(getSecondLargest(nums));
}
Here the code will give the second largest number and the index of it
const a = [1, 2, 3, 4, 6, 7, 7, 8, 15]
a.sort((a,b)=>a-b) //sorted small to large
const max = Math.max(...a)
const index = a.indexOf(max)
const s = {secondLargest:a[index-1],index:index-1}
console.log(s)
var elements = [21,23,34]
var largest = -Infinity
// Find largest
for (var i=0; i < elements.length; i++) {
if (elements[i] > largest) largest = elements[i]
}
var second_largest = -Infinity
var second_largest_position = -1
// Find second largest
for (var i=0; i < elements.length; i++) {
if (elements[i] > second_largest && elements[i] < largest) {
second_largest = elements[i]
second_largest_position = i
}
}
console.log(second_largest, second_largest_position)
function getSecondLargest(nums) {
let arr = nums.slice();//create a copy of the input array
let max = Math.max(...arr);//find the maximum element
let occ = 0;
for(var i = 0 ; i < arr.length ; i++)
{
if(arr[i] == max)
{
occ = occ +1;//count the occurrences of maximum element
}
}
let sortedArr =arr.sort(function(x, y) { return x > y; } );//sort the array
for(var i = 1 ; i <= occ ; i++){
sortedArr.pop()//remove the maximum elements from the sorted array
}
return Math.max(...sortedArr);//now find the largest to get the second largest
}
I write the most simple function with O(n) complexity using two variables max and secondMax with simple swapping logic.
function getSecondLargest(nums) {
let max = 0, secondMax = 0;
nums.forEach((num) => {
if (num > max) {
secondMax = max;
max = num;
} else if (num != max && num > secondMax) secondMax = num;
});
return secondMax;
}
here you can also deal with if the second largest or largest number is repeated
var nums =[2,3,6,6,5];
function getSecondLargest(nums) {
let secondlargets;
nums.sort(function(a, b){return a - b});
// all elements are in the accesindg order
// [1,2,3,5,6,6]
var highest;
// that is the last sorted element
highest = nums[nums.length-1];
nums.pop();
// through above statment we are removing the highest element
for(let i =0;i<nums.length-1;i++){
if(nums[nums.length-1]==highest){
/* here we remove gives this as conditon because might be the hiesht
had more indecis as we have in this question index(5) &index(6)
so remove the element till all positon have elemnt excepts the highest */
nums.pop()
}
else{
return nums[nums.length-1]
/* our array is already sorted and after removing thew highest element */
}
}
}
Please find a simple solution, without using inbuild functions:
Time complexity is O(n)
function secondLargest(arr) {
let prev = [0]
let i =1;
let largest =0;
while(i<arr.length){
let current = arr[i];
if(current > largest ) {
largest = current;
prev = arr[i-1];
} else if (current > prev && current < largest) {
prev = current
}
i++;
}
return prev;
}
let arr = [1,2,3,41,61,10,3,5,23];
console.log(secondLargest(arr));
Here is a simple solution using .sort() and new Set()
const array = [21, 23, 34, 34];
function getSecondLargest(arr){
return list = [...new Set(arr)].sort((a, b) => b - a)[1]
};
getSecondLargest(array);
In this case, if there are repeated numbers then they will be removed, and then will sort the array and find the second-largest number.
let arr=[12,13,42,34,34,21,42,39]
let uniqueArray=[...new Set(arr)]
let sortedArray=uniqueArray.sort((a,b)=>b-a)
console.log(sortedArray[1])
/* we can solve it with recursion*/
let count = 0; /* when find max then count ++ */
findSecondMax = (arr)=> {
let max = 0; /* when recursive function call again max will reinitialize and we get latest max */
arr.map((d,i)=>{
if(d > max) {
max = d;
}
if(i == arr.length -1) count++;
})
/* when count == 1 then we got out max so remove max from array and call recursively again with rest array so now count will give 2 here we go with 2nd max from array */
return count == 1 ? findSecondMax(arr.slice(0,arr.indexOf(max)).concat(arr.slice(arr.indexOf(max)+1))) : max;
}
console.log(findSecondMax([1,5,2,3]))
function getSecondLargest(nums) {
// Complete the function
var a = nums.sort();
var max = Math.max(...nums);
var rev = a.reverse();
for(var i = 0; i < nums.length; i++) {
if (rev[i] < max) {
return rev[i];
}
}
}
var nums = [2,3,6,6,5];
console.log( getSecondLargest(nums) );
Find Second Highest Number (Array contains duplicate values)
const getSecondHighestNumber = (numbersArry) => {
let maxNumber = Math.max( ...numbersArry);
let arrFiltered = numbersArry.filter(val => val != maxNumber);
return arrFiltered.length ? Math.max(...arrFiltered) : -1;
}
let items = ["6","2","4","5","5","5"];
const secondHighestVal = getSecondHighestNumber(items);
console.log(secondHighestVal); // 5
const arrData = [21, 23, 34];
const minArrValue = Math.min(...arrData);
const maxArrValue = Math.max(...arrData);
let targetHighValue = minArrValue;
let targetLowValue = maxArrValue;
for (i = 0; i < arrData.length; i++) {
if (arrData[i] < maxArrValue && arrData[i] > targetHighValue) {
targetHighValue = arrData[i];
}
if (arrData[i] > minArrValue && arrData[i] < targetLowValue) {
targetLowValue = arrData[i];
}
}
console.log('Array: [' + arrData + ']');
console.log('Low Value: ' + minArrValue);
console.log('2nd Lowest Value: ' + targetLowValue);
console.log('2nd Highest Value: ' + targetHighValue);
console.log('High Value: ' + maxArrValue);
Notice that if the max number appears multiple times in your array (like [6, 3,5,6,3,2,6]), you won't get the right output. So here is my solution:
function getSecondLargest(nums) {
// Complete the function
const sortedNumbers = nums.sort((a, b) => b - a);
const max = sortedNumbers[0];
const secondMax = sortedNumbers.find(number => number < max);
return secondMax;
}
const findSecondlargestNumber = (data) => {
let largest = null;
let secondlargest = null;
data.forEach(num => {
if(!largest) {
largest = num;
}
else if(num > largest) {
secondlargest = largest;
largest = num;
}
else if((!secondlargest && num !== largest) || (secondlargest)) {
secondlargest = num;
}
})
return secondlargest;
}
console.log(findSecondlargestNumber([11, 11, 3, 5, 6,2, 7]))
Here's the simplest way to get the second largest number and it's respective position from an array without rearranging the array or without using sorting method.
function findSecondLargest(arr) {
const largest = Math.max.apply(null, arr);
arr[arr.indexOf(largest)] = -Infinity;
const secondLargest = Math.max.apply(null, arr);
const position = arr.indexOf(secondLargest);
return { secondLargest, position };
}
console.log(findSecondLargest([3, 5, 7, 9, 11, 13])); //{ secondLargest: 11, position: 4 }
-Infinity is smaller than any negative finite number.
function getSecondLargest(nums) {
const len = nums.length;
const sort_arr = nums.sort();
var mynum = nums[len-1];
for(let i=len; i>0; i--){
if(mynum>nums[i-1]){
return nums[i-1];
}
}
}

Categories