Return a new array that is greater than its 2nd value - javascript

How to return a new array that its values are greater than its 2nd value. If the array that was passed to the function has less than two elements, function should return false.
For example,
greaterThanSecond([1,3,5,7])
should return [5, 7].
greaterThanSecond([0, -3, 2, 5])
should return [0, 2, 5].
greaterThanSecond([2])
should return false.
This is what I tried.
function valGreaterThanSecond(arr) {
for (let newArr of arr) {
if (newArr > arr[1]) {
return [newArr]
}else {
return false
}
}
}

You can try a one-liner:
[0, -3, 2, 5].filter((element, index, array) => element > array[1])
The filter function has 3 parameters:
The inspected elment
Index of the inspected element
The original array
The filter iterate through the array and you can compare to the original array's second element

function valGreaterThanSecond(arr) {
let resultArray = []
console.log(arr.length)
let checkValue = arr[1]
if(arr.length < 2)
return false
else
{
for(let i = 0 ; i < arr.length ; i++){
if(arr[i]!=checkValue && arr[i]>checkValue)
resultArray.push(arr[i])
}
return resultArray
}
}
console.log(valGreaterThanSecond([2]))
try this approach

You can try this
function greaterThanSecond(arr) {
if (arr.length < 2)
return false;
return arr.filter((item) => item > arr[1])
}
console.log(greaterThanSecond([0,-3,2,5]))

You can try this:
const greaterThanSecond = arr => {
if (arr.length > 1){
return arr.filter(e => e > arr[1])
}
return false
}
console.log(greaterThanSecond([1,3,5,7]))
In this function, at first you should check if the length of the array is not less than 2. Then we filter the array by checking if each number in the array is bigger than the second number and keep those ones in the array.

First let's try fixing your code before I am suggesting another approach.
function valGreaterThanSecond(arr) {
let newArr = [];
if (arr.length < 2) return false;
for (let elem of arr) {
if (elem > arr[1]) {
newArr = [...newArr, elem]
}
}
return newArr;
};
console.log(valGreaterThanSecond([1,3,5,7]));
The problem with your function is that once you found a number that is greater than the second element you immediately return it, thus exiting the function and returning this one element in an array, which is not what you want. If you found an element in the array that is not greater than the second element you immediately return false, which is not the behavior you want as well. In your example of [1,3,5,7] you will return false because 1 < 3 and you are out of the function at this point.
Different approach using reduce
I would like to suggest a different approach since there are a few answers using filter which is the first thing I would think about myself.
Here is a solution using the reduce function for arrays.
const greaterThanSecond = (arr) => {
if (arr.length < 2) return false;
const result = arr.reduce((acc, curr) => {
if (curr > arr[1]) return [...acc, curr];
return acc;
}, []);
return result;
}
console.log(greaterThanSecond([1,3,5,7]));

Related

find max elements of an array in JS, elements might be same

I know there are a lot of questions about how to get max from an array, but they all have unique elements. my scenario is different, for example:
find_multiple_max([10,20,30,30])
will return
[30, 30]
I found a solution and it works:
function find_multiple_max(arr) {
var max;
arr = arr.sort((a,b) => b-a)
.filter(e => {
if (!max) {
max = e;
return true;
}
return (e == max);
});
console.log(arr);
return arr;
}
I was still wondering if any simpler answer exists.
You can still use Math.max which will return the maximum element from the array and then use filter to get an array
function find_multiple_max(arr) {
let maxElem = Math.max(...arr);
return arr.filter(item => item == maxElem)
}
console.log(find_multiple_max([10, 20, 30, 30]))

javascript function to find the second largest element in an array

I am completing the hackerrank's 10 days of javascript challenge. The question:
write a function to take an array as an argument and then return the second largest element in the array.
I have written the code but my code is returning the largest element and not the second largest as asked.
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large=nums[0];
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&large<largest)
large=nums[j];
}
return large;
}
When input array nums={2,3,6,6,5} the result is coming 6 while expected output is 5. Please help and point out the errors in the function code below.
should not initialize large with first value var large=nums[0]; because it may appear the biggest value and won't work
should use nums[j]<largest instead of large<largest as mentioned above
I think don't need second loop as all checks can be done in first loop, and you can assign prev largest to large whenever you change it:
function getSecondLargest(nums) {
var largest = nums[0];
var large;
for (let i = 1; i < nums.length; ++i) {
if (nums[i] > largest) {
large = largest;
largest = nums[i];
} else if (nums[i] > large || typeof large === 'undefined') {
large = nums[i]
}
}
return large;
}
console.log(getSecondLargest([5,1-2,3]))
console.log(getSecondLargest([-5,1,-2,3]))
GET SECOND LARGEST
first, I create new array with unique values.
let arr = [...new Set(nums)];
second, sort value using built-in function .sort().
note : by default .sort() always sorts asciibetically, but for some testcase, it doesn't work. So, I put (a, b) => { return a - b } to make sure it will work properly.
arr = arr.sort((a, b) => { return a -b });
third, get the value from arr
let result = arr[arr.length - 2] || arr[0];
finally, return the result
return result
function getSecondLargest(nums) {
let arr = [...new Set(nums)];
//Javascript's array member method .sort( always sorts asciibetically.
arr = arr.sort((a, b) => { return a - b });
let result = arr[arr.length - 2] || arr[0];
return result
}
Just one minor change:
Use nums[j]<largest instead of large<largest in the second for loop
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large;
//To ensure that the selected number is not the largest
for(let j=0;j<nums.length;++j)
{
if (nums[j] !== largest){
large = nums[j];
break;
}
}
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&nums[j]!=largest)
large=nums[j];
else
console.log(large)
}
return large;
}
var secondLargest = getSecondLargest([6,3,6,6,5]);
console.log("Second largest number", secondLargest);
If you want to avoid using library functions like #ifaruki suggests, this line
if(large<nums[j]&&large<largest)
should read
if (large<nums[j] && nums[j] < largest)
Sorting and picking the second or second-to-last value fails when there are duplicates of the highest value in the input array.
Another easiest logic is to remove duplicates from the array and sort.
let givenArray = [2, 3, 6, 6, 5];
let uniqueArray = [...new Set(givenArray)];
console.log("The second largets element is", uniqueArray.sort()[uniqueArray.length - 2]);
I know you had your question answered, just thought I would provide my solution for any future users looking into this.
You can use reduce to go through the array while remembering the two largest numbers so far.
You just make a simple reduction function:
function twoMax(two_max, candidate)
{
if (candidate > two_max[0]) return [candidate,two_max[0]];
else if (candidate > two_max[1]) return [two_max[0],candidate];
else return two_max;
}
And then you use it for example like this:
let my_array = [0,1,5,7,0,8,12];
let two_largest = my_array.reduce(twoMax,[-Infinity,-Infinity]);
let second_largest = two_largest[1];
This solution doesn't require sorting and goes through the array only once.
If you want to avoid using **sort method. I think here's the easiest logic to do that, which will also work in arrays where there's duplicates of largest integer exists.
function getSecondLargest(arr) {
const largest = Math.max.apply(null, arr);
for (let i = 0; i < arr.length; i++) {
if (largest === arr[i]) {
arr[i] = -Infinity;
}
}
return Math.max.apply(null, arr);
}
console.log(getSecondLargest([5, 7, 11, 11, 11])); //7

how to print a unique number in a array

The problem is to find the unique number in a array such as [2,2,2,5].
The output should be 5 as it is the 1 unique element in the array.
I have attempted this:
function findUniq(arr) {
var b= arr[0];
var c;
for(var i=0; i<arr.length; i++)
{
if(arr[i]===b )
{
b=arr[i]
}
else
{
c=arr[i];
}
}
return c
console.log(findUniq([3, 5, 3, 3, 3]))
This works fine unless the unique number is the first element in the array. How do I fix this?
You can use indexOf and lastIndexOf to see if a value occurs more than once in the array (if it does, they will be different), and if so, it is not the unique value. Use filter to process the array:
let array = [2,2,2,5];
console.log(array.filter(v => array.indexOf(v) === array.lastIndexOf(v)));
array = [5,3,3,3,3];
console.log(array.filter(v => array.indexOf(v) === array.lastIndexOf(v)));
array = [4,4,5,4];
console.log(array.filter(v => array.indexOf(v) === array.lastIndexOf(v)));
You can create a recursive function that will take the first element of the array and see if it exists in the rest of it, if it does, it will take the next element and do the same, return the element if it doesn't exist in the rest of the array :
const arr = [3, 3, 3, 5, 3];
const find = arr => {
const [f, ...rest] = arr;
if(rest.includes(f))
return find(rest);
else
return f;
}
const result = find(arr);
console.log(result);
Note that this will return the last element if all of them are the same [3,3,3] will return 3
Try something like this using a set, which only stores unique elements:
var set = new Set(arr);
// count instances of each element in set
result = {};
for(var i = 0; i < a.length; ++i) {
if(!result[arr[i]])
result[arr[i]] = 0;
++result[arr[i]];
}
for (var value in result) {
if (value == 1) {
return value;
}
}
// if there isn't any
return false;
This should work, please tell me if it doesn't.
This is another implementation that is surely less efficient than that of #Nick's, but it is a valid algorithm anyway:
function findUniq(arr) {
var elemCount = new Map();
var uniq = [];
// Initialize elements conts
for (var k of arr.values()) {
elemCount.set(k, 0);
}
// Count elements
for (var k of arr.values()) {
elemCount.set(k, elemCount.get(k) + 1);
}
// Add uniq elements to array
for (var [k, v] of elemCount.entries()) {
if (v === 1) uniq.push(k);
}
return uniq;
}
console.log(findUniq([3, 5, 3, 3, 3]))
if you prefer .reduce over .map for your use case (for performance/etc. reasons):
function existance(data) {
return data.reduce((a, c) => (data.indexOf(c) === data.lastIndexOf(c)) ? a.concat(c) : a, []);
}
console.log(existance([1,1,1,2]));
console.log(existance([1,1,2,3,4,5,5,6,6,6]));

Remove all items that have duplicates in array Javascript

I have searched on here and have not found a solution. Obviously I will be corrected if I am wrong. What I am trying to do is return values that do not have a duplicates in an array.
Examples:
myArr = [2,1,2,3] // answer [1,3]
myArr = [3,1,2,2,3] // answer [1]
I would post some code but I have not been able to figure this out myself and the only code examples I have found are for removing any duplicate values.
The possible solution above is to return no duplicates... I am trying to return values that are don't have duplicates.
One option is to use the optional second argument to indexOf to find duplicate indexes. Consider that for a given element e and an index i:
if e is the first of two identical elements in the array, indexOf(e) will return i and indexOf(e, i + 1) will return the index of the second element.
if e is the second of two identical elements in the array, indexOf(e) will return the index of the first element, and indexOf(e, i + 1) will return -1
if e is a unique element, indexOf(e) will return i and indexOf(e, i + 1) will return -1.
Therefore:
myArr.filter(function (e, i, a) {
return a.indexOf(e) === i && a.indexOf(e, i + 1) === -1
});
var isUnique = function(v,i,arr){
// return true if the first occurrence is the last occurrence
return ( arr.indexOf(v) === arr.lastIndexOf(v) );
};
var uniqueVals = myArr.filter(isUnique);
console.log( uniqueVals );
If is not an associative array (your case):
var myArr = [1,2,2,3,4,4,1,5];
var myNewArr = [];
if (myArr.length > 0 )
{
myNewArr[0] = myArr[myArr.length-1];
}
var count = 1;
myArr.sort();
for (var i = myArr.length - 2; i >= 0; i--) {
if(myArr[i] != myArr[i-1])
{
myNewArr[count] = myArr[i];
count++;
}
}
var yourArray = [1, 2, 1, 3];
var uniqueValues = [];
$.each(yourArray, function (i, value) { //taking each 'value' from yourArray[]
if ($.inArray(value, uniqueValues) === -1) {
uniqueValues.push(value); // Pushing the non - duplicate value into the uniqueValues[]
}
});
console.log(uniqueValues);
Result: [1,2,3];

recursively putting array elements in their own array

I'm trying to create a function that puts each array element in its own array, recursively.
I think my base case is correct, but my recursive call doesn't appear to be working. any insight?
function ownList(arr){
if (arr.length === 1) {
arr[0] = [arr[0]];
return;
} else {
return arr[0].concat(ownList(arr.slice(1)));
}
}
var arr = [1,2,3]
console.log(ownList(arr))// returns []
//should return [[1],[2],[3]]
Here I'm trying to put each pair in it's own list (recursive only). This code below is correct (update)
function ownListPair(arr){
if (arr.length === 0)
return arr;
else if(arr.length === 1)
return [[arr[0], 0]];
else
return [[arr[0], arr[1]]].concat(ownListPair(arr.slice(2)));
}
// var arr = [3,6,8,1,5]
var arr = [2,7,8,3,1,4]
//returns [ [ 2, 7 ], [ 8, 3 ], [ 1, 4 ]]
console.log(ownListPair(arr))
I prefer this solution for several reasons:
function ownList(a) {
return a.length == 0
? []
: [[a[0]]].concat(ownList(a.slice(1)))
}
It's shorter and more concise
It works for empty arrays as well
The actual wrapping happens only once in the last line. Treating length == 1 separately -- as suggested by others -- is not necessary.
It would more appropriate to make a length of 0 be the null case. Then you just have to get the brackets right. The thing on the left side of the concat should be an array consisting of the array containing the first element.
function ownList(arr) {
return arr.length ? [[arr[0]]].concat(ownList(arr.slice(1))) : [];
}
Here's an alternative, take your pick:
function ownList(arr) {
return arr.length ? [[arr.shift()]] . concat(ownList(arr)) : [];
}
Using a bit of ES6 magic for readability:
function ownList([head, ...tail]) {
return head === undefined ? [] : [[head]] . concat(ownList(tail));
}
Here the [head, ...tail] is using parameter destructuring which pulls the argument apart into its first element (head) and an array of remaining ones (tail).
Instead of concat you could also use the array constructor:
function ownList([head, ...tail]) {
return head === undefined ? [] : Array([head], ...ownList(tail));
}
I think your basic assumption is wrong. What you need to do is check if each item in the array is an array, if not just add the item to the new array, if so have the function run itself on the array item.
That is recursion.
This code does that kind of recursion...
function ownList(arr)
{
var newArr = [];
var length = arr.length;
for (var i = 0; i < length; i++) {
if (typeof(arr[i]) === 'object') {
newArr.push(ownList(arr[i]));
continue;
}
newArr.push([arr[i]]);
}
return newArr;
}
var arr = [1, 2, 3];
console.log(ownList(arr));
Would something like this work:
var arr = [1, 2, 3, ["a", "b", "c", ["str"]]],
result = [];
function flatten(input){
input.forEach(function(el){
if(Array.isArray(el)){
flatten(el)
}else{
result.push([el]);
}
});
}
flatten(arr);
console.log(JSON.stringify(result));
//[[1],[2],[3],["a"],["b"],["c"],["str"]]
JSBIN
Edit:
var result = [];
function flatten(input){
if (input.length === 0){
console.log( "result", result ); //[[1],[2],[3],["a"],["b"],["c"],["str"]]
return;
}
//if zeroth el of input !array, push to result
if (!Array.isArray(input[0])){
result.push(input.splice(0, 1));
flatten(input);
}else{
flatten(input[0]); //else, give input[0] back to flatten
}
}
window.onload = function(){
var arr = [1, 2, 3, ["a", "b", "c", ["str"]]];
flatten(arr);
}
JSBIN
After struggling through this today, turns out that this works :)
function ownList(arr){
//base case:
if (arr.length === 1) {
return [arr];
}
//recurse
//have to do two brackets here --> (arr.slice(0,1)) since length > 1
return [arr.slice(0,1)].concat(ownList(arr.slice(1)));
}
var arr = [1,2,3]
console.log(ownList(arr))// returns [[1],[2],[3]]

Categories