Can't find a solution for array reverse algorithm problem - javascript

I have a requirement where I have to reverse an array without changing the index of '#' presents in an array, like below example:
Array [18,-4,'#',0,8,'#',5] should return [5, 8, "#", 0, -4, "#", 18], here numbers should be reversed, excluding '#' while keeping the same index.
I have tried to get the correct output, but it doesn't seem to be correct in all scenarios:
var arr = [18,-4,'#',0,8,'#',5]; // giving result is correct
var arr1 = [18,-4,0,'#',8,'#',5]; // result is not correct
var reverse = function(numbers, start, end){
var temp = numbers[start];
numbers[start] = numbers[end];
numbers[end] = temp;
}
var flip = function(numbers) {
var start = 0;
var end = numbers.length-1;
for(var i=0;i<parseInt(numbers.length/2);i++) {
if(numbers[i] === '#') {
start = i+1;
end = numbers.length - i - i;
reverse(numbers, start, end);
} else if (numbers[numbers.length - i - 1] === '#') {
start = i;
end = numbers.length - i - 2;
reverse(numbers, start, end);
} else {
reverse(numbers, start, end);
}
}
return numbers;
}
var arr = [18,-4,'#',0,8,'#',5];
var arr1 = [18,-4,0,'#',8,'#',5];
console.log(flip(arr));
console.log(flip(arr1));

You could simplify the function and use only two indices, the start and end and check if the value at the indices should stay, then choose another index for swapping.
const
swap = (array, a, b) => [array[a], array[b]] = [array[b], array[a]],
flip = numbers => {
var start = 0,
end = numbers.length - 1;
while (start < end) {
if (numbers[start] === '#') {
start++;
continue;
}
if (numbers[end] === '#') {
end--;
continue;
}
swap(numbers, start++, end--);
}
return numbers;
},
array1 = [18, -4, '#', 0, 8, '#', 5],
array2 = [18, -4, 0, '#', 8, '#', 5];
console.log(...flip(array1));
console.log(...flip(array2));

The trivial approach would be to remove all '#''s, reverse the array using the built in [].reverse method, and then re-insert the '#''s:
let flip = numbers => {
let removed = numbers.reduce((r, v, i) =>
v === '#' ? r.concat(i) : r
, []);
let reversed = numbers.filter(v => v !== '#').reverse();
removed.forEach(i => reversed.splice(i, 0, '#'));
return reversed;
};
let arr = [18, -4, '#', 0, 8, '#', 5];
let arr1 = [18, -4, 0, '#', 8, '#', 5];
console.log(flip(arr));
console.log(flip(arr1));

You can try this:
var numbers = arr.filter(a => a !== '#')
var revArr = [];
arr.forEach((currentValue) => {
if(currentValue !== "#") {
revArr.push(numbers.pop());
} else {
revArr.push("#");
}
});

You can base your algorithm on two basic array (array of reversed numbers and and an array with "#" saved positions)
const array = [5, 8, "#", 0, -4, "#", 18];
function flip(array) {
const arrayNumbers = array.filter((el, index) => el !== "#").reverse();
var counter = 0;
return array.map(el => el === "#").map(el => {
if (!el) {
let num = arrayNumbers[counter];
counter = counter + 1;
return num;
} else {
return "#"
}
})
}
console.log(flip(array));

var arr = [18,-4,'#',0,8,'#',5]
var stack = []
for (i=0 ; i<arr.length; i++) {
if (arr[i] == '#') continue;
stack.push(arr[i]);
}
for (i=0 ; i<arr.length; i++) {
if (arr[i] != '#') {
arr[i] = stack.pop();
}
}
console.log(arr)
The above code should solve your problem.
The implementation uses stack where we keep inserting elements into stack untill we see a '#' and skip it.
While creating the output array we refer the original array for '#' index and stack for reverse index.

You can do it like this.
int end = v.length - 1;
int start = 0;
for (int i = 0; i < v.length >> 1; i++) {
if (v[start].equals("#")) {
start++;
continue;
}
if (v[end].equals("#")) {
end--;
continue;
}
Object temp = v[end];
v[end] = v[start];
v[start] = temp;
end--;
start++;
}
System.out.println(Arrays.toString(v));

Related

How to Make Consecutive Numbers from an Array

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]))

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];
}

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];
}
}
}

Get elements that has no double value in an array

I have a question . How do you retrieve elements that has no double value in an array?? For example: [1,1,2,2,3,4,4,5] then you retrieve [3,5] only.
Thanks in advance
for (var j = 0; j < newArr.length; j++) {
if ((arr1.indexOf(newArr[j]) === 0) && (arr2.indexOf(newArr[j]) === 0)) {
index = newArr.indexOf(j); newArr.splice(index, 1);
}
}
If the item in the array is unique then the index found from the beginning should equal the index found from the end, in other words:
var xs = [1, 1, 2, 2, 3, 4, 4, 5];
var result = xs.filter(function(x) {
return xs.indexOf(x) === xs.lastIndexOf(x);
});
console.log(result); //=> [3, 5]
sorry for the presentation its my first post !
You have to compare each element of your array to the others in order to get the number of occurence of each element
var tab = [1,1,2,2,3,4,4,5] //The array to analyze
tab = tab.sort(); // we sort the array
show(tab); // we display the array to the console (F12 to open it)
var uniqueElementTab = []; // this array will contain all single occurence
var sameElementCounter = 0;
for(x=0;x<tab.length;x++){ // for all element in the array
sameElementCounter = 0;
for(y=0;y<tab.length;y++){ // we compare it to the others
if((tab[x]==tab[y])){
sameElementCounter+=1; // +1 each time we meet the element elsewhere
}
}
if(sameElementCounter<=1){
uniqueElementTab.push(tab[x]); //if the element is unique we add it to a new array
}
}
show(uniqueElementTab); // display result
function show(tab) { // Simple function to display the content of an array
var st="";
for(i=0;i<tab.length;i++){
st += tab[i]+" ";
}
console.log(st+"\n");
}
Hope it helps.
Here is a simple "tricky" solution using Array.sort, Array.join, Array.map, String.replace and String.split functions:
var arr = [1, 1, 2, 2, 3, 4, 4, 5];
arr.sort();
var unique = arr.join("").replace(/(\d)\1+/g, "").split("").map(Number);
console.log(unique); // [3, 5]
create new array tmp,and check already value exist by indexOf .If existed delete by splice function..
var arr = [1,1,2,2,3,4,4,5];
var tmp = [];
var dup = [];
for(var i = 0; i < arr.length; i++){
var ind = tmp.indexOf(arr[i]);
if(ind == -1){
if(dup.indexOf(arr[i]) == -1){
tmp.push(arr[i]);
}
}
else{
tmp.splice(ind,1);
dup.push(arr[i]);
}
}
console.log(tmp);
This would be my way of doing this job.
var arr = [1,1,2,2,3,4,4,5],
uniques = Object.keys(arr.reduce((p,c) => (c in p ? Object.defineProperty(p, c, {enumerable : false,
writable : true,
configurable : true})
: p[c] = c,
p), {}));
console.log(uniques);
A solution for unsorted arrays with a hash table for the items. Complexity O(2n)
var array = [1, 1, 2, 2, 3, 4, 4, 5, 1],
hash = Object.create(null),
single;
array.forEach(function (a, i) {
hash[a] = a in hash ? -1 : i;
});
single = array.filter(function (a, i) {
return hash[a] === i;
});
console.log(single);
If the array is sorted, you can solve this in O(n) (see "pushUniqueSinglePass" below):
function pushUniqueSinglePass(array, unique) {
var prev; // last element seen
var run = 0; // number of times it has been seen
for (var i = 0; i < array.length; i++) {
if (array[i] != prev) {
if (run == 1) {
unique.push(prev); // "prev" appears only once
}
prev = array[i];
run = 1;
} else {
run++;
}
}
}
function pushUniqueWithSet(array, unique) {
var set = new Set();
for (var i = 0; i < array.length; i++) {
set.add(array[i]);
}
for (let e of set) {
unique.push(set);
}
}
// Utility and test functions
function randomSortedArray(n, max) {
var array = [];
for (var i = 0; i < n; i++) {
array.push(Math.floor(max * Math.random()));
}
return array.sort();
}
function runtest(i) {
var array = randomSortedArray(i, i / 2);
var r1 = [],
r2 = [];
console.log("Size: " + i);
console.log("Single-pass: " + time(
pushUniqueSinglePass, array, r1));
console.log("With set: " + time(
pushUniqueWithSet, array, r2));
// missing - assert r1 == r2
}
[10, 100, 1000, 10000,
100000, 1000000
].forEach(runtest);
function time(fun, array, unique) {
var start = new Date().getTime();
fun(array, unique);
return new Date().getTime() - start;
}
This is much more efficient than using maps or sorting (time it!). In my machine, a 1M sorted array can have its unique elements found in 18 ms; while the version that uses a set requires 10x more.

Array Pattern using Javascript

I have an array: Myarray=[1,0,0,1,0,1,1,0,0]
I want to display the elements of the array in the pattern 1,0,1,0..
I tried to set a flag:
for (var i = 0; i < myArray.length; i++) {
if (myArray[i] == flag) {
newArray = newArray + myArray[i];
if (flag == 0)
flag = 1;
else
flag = 0;
}
But the problem is the mismatched elements are not showing in output.
Any Idea? Thanks.
Generating a new Array of 1, 0, 1, 0, ... with length equal to myArray.length can be done in one line with Array.prototype.map
var newArr = myArray.map(function (e, i) {return 1 - (i % 2);});
However, it may be more efficient to use a loop;
var newArr = [],
i = myArray.length;
while (i-- > 0)
newArr[i] = 1 - (i % 2);
newArr; // [1, 0, 1, 0, 1, 0, 1, 0, 1]
If you want to filter out consecutive repeating items, you can use Array.prototype.filter with a variable outside the filter function to remember what you last saw
var newArray = (function () {
var last;
return myArray.filter(function (e) {
var t = last;
last = e;
if (t === last)
return false;
return true;
});
}());
Or again in a loop
var newArr = [],
last,
i;
for (i = 0; i < myArray.length; ++i)
if (last !== myArray[i]) {
last = myArray[i];
newArr.push(last);
}
newArr; // [1, 0, 1, 0, 1, 0]
Just initialize newArray to the first element of your Array then enter the for-loop checking if the next value is not equal to the last element of new array. Your code will look something like:
newArray[0]=myArray[0];
for (var i = 1; i < myArray.length; i++) {
if(newArray[i-1]!=myArray[i]) {
newArray.push(myArray[i]);
}
}
Pulling only elements that match a pattern:
var a = [1,0,0,1,0,1,1,0,0],
pat = [1,0,1,0,1,0,1,0,1],
matched = a.map(function(a1, idx) { return a[idx] === pat[idx] ? a1 : null } );
console.log(matched); // [1, 0, null, null, null, null, 1, 0, null]

Categories