I have three sorted array I need to find top five "5" element from these array .I am able to find first two element largest element .how I will find other ?
can you suggest how we can find other 3 element ?
here is my code
var maxArray=[];
var array1=[2,7,12,23,40,44,67,88,102]
var array2=[3,12,14,17,23,40,41,67,108]
var array3=[8,12,23,40,59,86,119,130]
var firstMax=array1[array1.length-1];
var secondMax=array2[array2.length-1];
alert(array1[array1.length-1]);
if(array1[array1.length-1]>array2[array2.length-1] && array1[array1.length-1]>array3[array3.length-1]){
maxArray.push(array1[array1.length-1]) ;
firstMax=array1[array1.length-1];
if(array2[array2.length-1]>array3[array3.length-1]){
secondMax=array2[array2.length-1];
}else {
secondMax=array3[array3.length-1];
}
}else if(array2[array2.length-1]>array1[array1.length-1]&& array2[array2.length-1]>array3[array3.length-1]){
maxArray.push(array1[array2.length-1])
firstMax=array2[array2.length-1];
if(array1[array1.length-1]>array3[array3.length-1]){
secondMax=array1[array1.length-1];
}else {
secondMax=array3[array3.length-1];
}
}else{
maxArray.push(array3[array3.length-1])
firstMax=array3[array3.length-1];
if(array2[array2.length-1]>array1[array1.length-1]){
secondMax=array2[array2.length-1];
}else {
secondMax=array1[array1.length-1];
}
}
maxArray.push(secondMax)
alert(maxArray)
fiddle
http://jsfiddle.net/9vsjm8uh/
jsFiddle (yep, even better without jQuery, thanks #Rajacsp)
var array1 = [2, 7, 12, 23, 40, 44, 67, 88, 102]
var array2 = [3, 12, 14, 17, 23, 40, 41, 67, 108]
var array3 = [8, 12, 23, 40, 59, 86, 119, 130]
var flatArray = array1.concat(array2).concat(array3);
flatArray.sort(function sortNumber(a, b) { return b - a; });
var maxArray = flatArray.slice(0, 5);
alert(maxArray); // 130,119,108,102,88
I would suggest the following idea:
Since you are looking for the top 5 values, they will, at worst case, all be in the same list. Thus, there are at most 5 * 3 = 15 values to check.
Then, you can take the 5 highest values from each list (which should be trivial if the list is already sorted), and then put them in another list. Now you have a list of the 15, and you want to find the top 5 values from this list. There are different ways to do this - you could sort the list, then take the top 5 values, or you can simply iterate through the list, finding the max each time.
Combine all of the arrays, sort them, then get the last 5 values.
var total = array1.concat(array2, array3);
total = total.sort(function(a,b){return a-b});
//Now total[length-5] is the 5th largest value
//total[length-4] is the 4th largest and so on
Plain Javascript (no libraries added):
var array1=[2,7,12,23,40,44,67,88,102];
var array2=[3,12,14,17,23,40,41,67,108];
var array3=[8,12,23,40,59,86,119,130];
alert(getTopFive(array1, array2, array3));
function getTopFive(ar1, ar2, ar3){
var finalArray = array1.concat(array2).concat(array3);
finalArray.sort(function sortInverse(a,b) { return b - a; });
return finalArray.slice(0, 5);
}
Related
I have a List of ages and a List of ageRanges, using javascript I am tying to filter the ages that fall within any of the ageRanges
I got code working for a single ageRange, but how can I do this if ageRanges is an array?
Example of code I used with a single ageRange:
var ages = [32, 33, 16, 22, 40];
var ageRanges = {min: 10, max:23};
function checkAdult(age) {
return age >= ageRanges.min && age <= ageRanges.max;
}
function myFunction() {
document.getElementById("demo").innerHTML = ages.filter(checkAdult);
} //returns 16,22
Example of the data I want to filter:
var ages = [32, 33, 16, 22, 40];
var ageRanges = [{min: 10, max:23},{min:30, max:36},{min:44, max:49}];
I tried doing a for loop, but struggled to get it right as I'm definitely new to all this so any help would be appreciated. Also started to wonder if a for loop was even the riI can easily format the ageRanges data differently if there is a better way to represent a list of ranges
So, use Array.prototype.some() along with Array.prototype.filter():
const ages = [32, 33, 16, 22, 40],
ageRanges = [{min: 10, max:23},{min:30, max:36},{min:44, max:49}],
result = ages.filter(age =>
ageRanges.some(({min,max}) =>
age >= min && age <= max))
console.log(result)
This is my task that Im stuck on a bit:
Write a function which receives two parameters, an array and an index. The function will print the value of the element at the given position (one-based) to the console.
For example, given the following array and index, the function will print 6.
var array = [3,6,67,6,23,11,100,8,93,0,17,24,7,1,33,45,28,33,23,12,99,100];
var index = 1;
I managed to do the opposite, using indexOf, which prints the index position:
let index6 = array2.indexOf(6);
console.log(index6);
But I am not sure how to solve this.
It's just an ordinary array index:
var array = [3, 6, 67, 6, 23, 11, 100, 8, 93, 0, 17, 24, 7, 1, 33, 45, 28, 33, 23, 12, 99, 100];
var index = 1;
function print_array_element(arr, i) {
console.log(arr[i]);
}
print_array_element(array, index);
The instructions say that the index should be one-based, but that's not what the example does. If it should be one-based, subtract 1 from the index argument: arr[i-1].
We have array of numbers, we need to find the total number of ways that we can remove one number in the array if removing that, will sort the array.
For example if we have [3,4,5,4] we should return 2 because if we remove 5 or the second 4 our array will be sorted.
But if we get something like [4,5,2,3,4] we should return 0 because removing any of them will not sort the array.
I believe that this is something related to Longest increasing subsequence
Correct me if I'm wrong, but this should work like this :
We should find the longest increasing subsequence and delete everything not in that subsequence.
With that in mind, I used some function like this to find the LIS :
function findSubsequence(arr){
var allSubsequence = [],
longestSubsequence = null,
longestSubsequenceLength = -1;
for(var i=0;i<arr.length;i++){ //i=1
var subsequenceForCurrent = [arr[i]],
current = arr[i],
lastElementAdded = -1;
for(var j=i;j<arr.length;j++){
var subsequent = arr[j];
if((subsequent > current) && (lastElementAdded<subsequent)){
subsequenceForCurrent.push(subsequent);
lastElementAdded = subsequent;
}
}
allSubsequence.push(subsequenceForCurrent);
}
for(var i in allSubsequence){
var subs = allSubsequence[i];
if(subs.length>longestSubsequenceLength){
longestSubsequenceLength = subs.length;
longestSubsequence = subs;
}
}
return longestSubsequence;
}
(function driver(){
var sample = [87,88,91, 10, 22, 9,92, 94, 33, 21, 50, 41, 60, 80];
console.log(findSubsequence(sample));
})();
But this give me the highest numbers, I'm not sure how should I remove one of them to keep the array sort and find all possible ways.
Any Idea?
That approach seems a bit complicated. I think it would be clearer and less resource-heavy to use a brute force approach: for every item in the array, try removing it, and then check to see if the array is sorted afterwards. But don't use sort to check if it's sorted (that has O(N log N) complexity), instead, just check to see that every item in the array is the same or greater than the previous one (O(N)):
const checkSorted = arr => arr.every((num, i, arr) => i === 0 || num >= arr[i - 1]);
const checkRemovalCount = arr => arr.reduce((countSoFar, _, i, arr) => {
const removedArr = [...arr.slice(0, i), ...arr.slice(i + 1)];
return countSoFar + checkSorted(removedArr);
}, 0);
console.log(checkRemovalCount([3,4,5,4]));
console.log(checkRemovalCount([4,5,2,3,4]));
console.log(checkRemovalCount([87,88,91, 10, 22, 9,92, 94, 33, 21, 50, 41, 60, 80]));
You can remove highest number using Math Library.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
var sample = [87,88,91, 10, 22, 9,92, 94, 33, 21, 50, 41, 60, 80];
sample.sort(function(a, b){return a - b});
list = remove_highest(sample)
console.log(list) // [9, 10, 21, 22, 33, 41, 50, 60, 80, 87, 88, 91, 92]
function remove_highest(list) {
return list.filter(function(n) { return n != Math.max.apply( Math, list ) })
}
</script>
</body>
</html>
In short, is there a way to exit the loop if my condition is met in a functional way?
Let me elaborate.
Let's say I have an array:-
var arr = [4,6,2,24,16,13,88,64,28,39,66,26,9]
and I want to extract the first odd number from arr.
My initial thought was that I could just use .some and get the first element whenever my condition is met but when I went over MDN I quickly found out that it's not as simple as I thought it would be cause .some only returns boolean value.
So, my another approach was to use .filter which would filter out all the odd numbers and grab the first one but doing this will make the loop go through the entire array even though filter has already found the first odd number in the loop. This is okay for small arrays but for arrays with huge elements, it feels that this is quite unnecessary.
Am I missing something with functional technique or is this usually how functional programming goes?
Just for the reference my solution with .some and .filter are:-
var result1, result2;
//Loop ends on the right element but result wrong value
var arr = [4, 6, 2, 24, 16, 13, 88, 64, 28, 39, 66, 26, 9];
result1 = arr.some(function (i) {
return i % 2;
});
//Has right value but loop continues till the end
result2 = arr.filter(function (i) {
return i % 2;
})[0];
You can use some with a variable to store the first odd value.
Fiddle
var arr = [4, 6, 2, 24, 16, 13, 88, 64, 28, 39, 66, 26, 9];
var odd = 0;
arr.some(function(i) {
console.log(i); // To check if this loop over all the elements of array
odd = i; // Assign the value
return i % 2;
});
document.write(odd);
You can use array.prototype.find - included on that page is a polyfill for stupid browsers
usage:
result1 = arr.find(function(i){
return i%2;
});
Try using a while loop
var arr = [4, 6, 2, 24, 16, 13, 88, 64, 28, 39, 66, 26, 9];
var i = 0;
// should break if odd number found,
// `i` would be index of first odd number found in `arr`
while (arr[i] % 2 === 0 && i < arr.length) {
++i;
};
console.log(arr[i])
I have a need to add or prepend elements at the beginning of an array.
For example, if my array looks like below:
[23, 45, 12, 67]
And the response from my AJAX call is 34, I want the updated array to be like the following:
[34, 23, 45, 12, 67]
Currently I am planning to do it like this:
var newArray = [];
newArray.push(response);
for (var i = 0; i < theArray.length; i++) {
newArray.push(theArray[i]);
}
theArray = newArray;
delete newArray;
Is there a better way to do this? Does JavaScript have any built-in functionality that does this?
The complexity of my method is O(n) and it would be really interesting to see better implementations.
Use unshift. It's like push, except it adds elements to the beginning of the array instead of the end.
unshift/push - add an element to the beginning/end of an array
shift/pop - remove and return the first/last element of an array
A simple diagram...
unshift -> [array] <- push
shift <- [array] -> pop
and chart:
add remove start end
push X X
pop X X
unshift X X
shift X X
Check out the MDN Array documentation. Virtually every language that has the ability to push/pop elements from an array will also have the ability to unshift/shift (sometimes called push_front/pop_front) elements, you should never have to implement these yourself.
As pointed out in the comments, if you want to avoid mutating your original array, you can use concat, which concatenates two or more arrays together. You can use this to functionally push a single element onto the front or back of an existing array; to do so, you need to turn the new element into a single element array:
const array = [3, 2, 1]
const newFirstElement = 4
const newArray = [newFirstElement].concat(array) // [ 4, 3, 2, 1 ]
console.log(newArray);
concat can also append items. The arguments to concat can be of any type; they are implicitly wrapped in a single-element array, if they are not already an array:
const array = [3, 2, 1]
const newLastElement = 0
// Both of these lines are equivalent:
const newArray1 = array.concat(newLastElement) // [ 3, 2, 1, 0 ]
const newArray2 = array.concat([newLastElement]) // [ 3, 2, 1, 0 ]
console.log(newArray1);
console.log(newArray2);
var a = [23, 45, 12, 67];
a.unshift(34);
console.log(a); // [34, 23, 45, 12, 67]
With ES6, use the spread operator ...:
Demo
var arr = [23, 45, 12, 67];
arr = [34, ...arr]; // RESULT : [34,23, 45, 12, 67]
console.log(arr)
Another way to do that is through concat:
var arr = [1, 2, 3, 4, 5, 6, 7];
console.log([0].concat(arr));
The difference between concat and unshift is that concat returns a new array. The performance between them could be found here.
function fn_unshift() {
arr.unshift(0);
return arr;
}
function fn_concat_init() {
return [0].concat(arr)
}
Here is the test result:
Quick Cheatsheet:
The terms shift/unshift and push/pop can be a bit confusing, at least to folks who may not be familiar with programming in C.
If you are not familiar with the lingo, here is a quick translation of alternate terms, which may be easier to remember:
* array_unshift() - (aka Prepend ;; InsertBefore ;; InsertAtBegin )
* array_shift() - (aka UnPrepend ;; RemoveBefore ;; RemoveFromBegin )
* array_push() - (aka Append ;; InsertAfter ;; InsertAtEnd )
* array_pop() - (aka UnAppend ;; RemoveAfter ;; RemoveFromEnd )
Using ES6 destructuring (avoiding mutation off the original array):
const newArr = [item, ...oldArr]
Without Mutating
Actually, all unshift/push and shift/pop mutate the source array.
The unshift/push add an item to the existed array from begin/end and shift/pop remove an item from the beginning/end of an array.
But there are few ways to add items to an array without a mutation. the result is a new array, to add to the end of array use below code:
const originArray = ['one', 'two', 'three'];
const newItem = 4;
const newArray = originArray.concat(newItem); // ES5
const newArray2 = [...originArray, newItem]; // ES6+
To add to begin of original array use below code:
const originArray = ['one', 'two', 'three'];
const newItem = 0;
const newArray = (originArray.slice().reverse().concat(newItem)).reverse(); // ES5
const newArray2 = [newItem, ...originArray]; // ES6+
With the above way, you add to the beginning/end of an array without a mutation.
You have an array: var arr = [23, 45, 12, 67];
To add an item to the beginning, you want to use splice:
var arr = [23, 45, 12, 67];
arr.splice(0, 0, 34)
console.log(arr);
Cheatsheet to prepend new element(s) into the array
1. Array#unshift
const list = [23, 45, 12, 67];
list.unshift(34);
console.log(list); // [34, 23, 45, 12, 67];
2. Array#splice
const list = [23, 45, 12, 67];
list.splice(0, 0, 34);
console.log(list); // [34, 23, 45, 12, 67];
3. ES6 spread...
const list = [23, 45, 12, 67];
const newList = [34, ...list];
console.log(newList); // [34, 23, 45, 12, 67];
4. Array#concat
const list = [23, 45, 12, 67];
const newList = [32].concat(list);
console.log(newList); // [34, 23, 45, 12, 67];
Note: In each of these examples, you can prepend multiple items by providing more items to insert.
If you need to continuously insert an element at the beginning of an array, it is faster to use push statements followed by a call to reverse, instead of calling unshift all the time.
Benchmark test: http://jsben.ch/kLIYf
Using splice we insert an element to an array at the begnning:
arrName.splice( 0, 0, 'newName1' );
If you want to push elements that are in an array at the beginning of your array, use <func>.apply(<this>, <Array of args>):
const arr = [1, 2];
arr.unshift.apply(arr, [3, 4]);
console.log(arr); // [3, 4, 1, 2]