How to make min() choose two numbers - javascript

I would like min() to choose the two smallest numbers in a list, is this possible and how should I do it?

actually, Math.min only gives you the single smallest of a list, so you need to simply sort them all and grab the quantity you need:
list = [7,4,5,4,2,23,4,6,4,6];
smalls = list.sort(function(a,b){return a-b}).slice(0,2);
alert(smalls); // shows "2, 4"

Sorting is a little inefficient as it takes up O(n log n) time. You could do the same thing with a single pass. Just keep to variables that are initialized to empty (or negative inifinity) or something.
For every element encountered, check against the two variables and update accordingly.
It is pretty simple but it takes up only linear time O(n).

Search for a documentation on "Math" (it is a javascript object with many useful math related functions and variables).
Hint.

Related

Why is Set.prototype.has() much faster than Array.prototype.includes()? Node v10

I have two arrays of strings, both having a length of ~150000.
I wanted to find shared elements between the two, so I used filter() on array1, and for each element checked if array2.includes[array1element].
this was taking around 1.5 mins to finish executing,
however when I changed the arrays to sets, and used set2.has(set1element), it executed in <1s
to filter.
I spread the contents of set1 into an array, but searching is being done on set2 using Set.prototype.has().
I'm new to sets, I actually just discovered them because arrays were taking so long to search through and I was looking for alternatives.
Can someone explain why there is such a significant time difference? I don't have much of a maths background so answers with less mathematical/algorithmic jargon are appreciated!
CODE:
where wireBpath and wireApath are arrays of strings: runtime ~1.5mins
let intersections = wireBpath.filter(position => wireApath.includes(position));
where wireBpath is an array(spread from a set to use the filter() method), and wireApath is a set: runtime<1s
let intersections = wireBpath.filter(position => wireApath.has(position));```
That is because the time complexity is different for Set and Array
The methods used by Sets to search for items has a time complexity of just O(1), but the methods an array uses to search for items has a linear time complexity of O(N). In other words, the run-time increases at the same rate as the size of the data increases.
For more details you can see this article

knockout.js compare 2 arrays without looping through them both

I have 2 observable arrays and within an if statement I want to do something only if the arrays are identical, is there any way to do this without looping through each?
Generally speaking, no. You cannot differentiate an apple from an orange if you don't see that the apple is an apple and the orange is an orange. You can, however, use heuristics/shortcuts, such as:
Is the length of them equal? If not, then sure as hell, they are different.
Does the order of elements matter? If yes, the first time you find a difference, you can terminate early with a negative answer.
Also a few things to note about the JSON approach posted in the other answer:
It will not work if the order of items does not matter
It will not work if any object in the array contains circular references
It will not work if there are objects with the same properties and values but the keys are in a different order. For example: { a: 1, b: 2 } and { b: 2, a: 1 } would normally be considered equal (unless your explicit purpose is object reference equality) but the JSON representation of these will be different.
It is slower, because just to produce the JSONs you need to iterate over all properties anyway and you need to iterate over the individual characters of the JSON to perform the comparison.
So to sum it up, while it might be a tiny bit shorter and easier to read, there are several caveats, which might or might not mean a problem depending on your requirements.
You can call ko.toJSON on both arrays and then compare the json strings that are returned. Functionally that's probably just as much work if not more for the processor as looping through both arrays but it does look cleaner if that's all you're going for.
isEqual = ko.toJSON(aryA) === ko.toJSON(aryb)

Is it a bad idea to use indexOf inside loops?

I was studying big O notation for a technical interview and then I realized that javascript's indexOf method may have a time complexity of O(N) as it traverses through each element of an array and returns the index where its found.
We also know that a time complexity of O(n^2) (n square) is not a good performance measure for larger data.
So is it a bad idea to use indexOf inside loops? In javascript, its common to see code where indexOf method is being used inside loops, may be to measure equality or to prepare some object.
Rather than arrays, should we prefer objects wherever necessary as they provide lookup with constant time performance O(1).
Any suggestions will be appreciated.
It can be a bad idea to use indexOf inside loops especially if the dataStructure you are searching through is quite large.
One work around for this is to have a hash table or dictionary containing the index of every item which you can generate in O(N) time by looping through the data structure and updating it every time you add to the data structure.
If you push something on the end of the data structure it will take O(1) Time to update this table and the worst case scenario is if you push something to the beginning of the data structure it will take O(N).
In most scenarios it will be worth it as getting the index will be O(1) Time.
To be honest, tl;dr. But, I did some speed tests of the various ways of checking for occurrences in a string (if that is your goal for using indexOf. If you are actually trying to get the position of the match, I personally don't know how to help you there). The ways I tested were:
.includes()
.match()
.indexOf()
(There are also the variants such as .search(), .lastIndexOf(), etc. Those I have not tested).
Here is the test:
var test = 'test string';
console.time('match');
console.log(test.match(/string/));
console.timeEnd('match');
console.time('includes');
console.log(test.includes('string'));
console.timeEnd('includes');
console.time('indexOf');
console.log(test.indexOf('string') !== 0);
console.timeEnd('indexOf');
I know they are not loops, but show you that all are basically the same speed. And honestly, each do different things, depending on what you need (do you want to search by RegEx? Do you need to be pre ECMAScript 2015 compatible? etc. - I have not even listed all of them) is it really necessary to analyze it this much?
From my tests, sometimes indexOf() would win, sometimes one of the other ones would win.
based on the browser, the indexOf has different implementations (using graphs, trees, ...). So, the time complexity for each indexOf also differs.
Though, what is clear is that implementing indexOf to have O(n) would be so naive and I don't think there is a browser to have it implements like a simple loop. Therefore, using indexOf in a for loop is not the same as using 2 nested for loops.
So, this one:
// could be O(n*m) which m is so small
// could be O(log n)
// or any other O(something) that is for sure smaller than O(n^2)
console.time('1')
firstArray.forEach(item => {
secondArray.indexOf(item)
})
console.time('1')
is different than:
// has O(n^2)
console.time('2')
firstArray.forEach(item => {
secondArray.forEach(secondItem => {
// extra things to do here
})
})
console.time('2')

Java Script Randomize Array Function

Trying to plan out a function and I wanted to get some input. I am trying to find an efficient way to:
Double the frequency of numbers in an array
Randomize the location of the values in the array.
For example: Lets say I have an array. [0,1,2,3]
first I want to duplicate each number once in a new array. So now we would have something like this.
[0,0,1,1,2,2,3,3].
Lastly, I want to randomize these values so: [0,4,2,3,0,2,3,4]
Eventually, the algorithm I write will need to handle an initial array of 18 digits (so the final, randomized array will be of size 36)
My initial thoughts are to just have a simple while loop that:
Randomly selects a spot in the new array
Checks to see if it is full
-If it is full, then it will select a new spot and check again.
If it is not full, then it will place the value in the new array, and go to the next value.
I am leaving out some details, etc. but I want this algorithm to be fairly quick so that the user doesn't notice anything.
My concern is that when there is only one digit left to be placed, the algorithm will take forever to place it because there will be a 1/36 chance that it will select the empty space.
In general terms, how can I make a smarter and faster algorithm to accomplish what I want to do?
Many thanks!
first I want to duplicate each number once in a new array. So now we would have something like this. [0,0,1,1,2,2,3,3].
That would be rather complicated to accomplish. Since the positions are not relevant anyway, just build [0,1,2,3,0,1,2,3] by
var newArray = arr.concat(arr);
Lastly, I want to randomize these values so: [0,4,2,3,0,2,3,4]
Just use one of the recognized shuffle algorithms - see How to randomize (shuffle) a JavaScript array?. There are rather simple ones that run in linear time and do not suffer from the problem you described, because they don't need to randomly try.
Here is an alternative to the known methods with two arrays, I came up with. It gives relatively good randomization.
var array1=[]
var array=[0,1,2,3,0,1,2,3]
a=array.length;
b=a;
c=b;
function rand(){for (i=0;i<c;i++){
n=Math.floor(Math.random()*b);
array1[i]=array[n]; array.splice(n,1);b--;}
for (i1=0;i1<c;i1++){array[i1]=array1[i1]}

JavaScript sort with numbers

The following program (taken from a tutorial) prints the numbers in an array in order from lowest to highest. In this case, the result will be 2,4,5,13,31
My question relates to the paramaters "a" and "b" for the function compareNumbers. When the function is called in numArray.sort(compareNumbers) what numbers will be the parameters a and b for the function. Does it just move along the array. For example, start with a=13 and b=2? After that, does the function run again comparing a=2 and b=31? or would it next compare a=31 and b=4?
Can someone please explain how that part works and also how it manages to sort them from lowest to highest? I don`t see how the function manages to do the necessary calculations on the numbers in the array.
function compareNumbers(a,b) {
return a - b;
}
var numArray = [13,2,31,4,5];
alert(numArray.sort(compareNumbers));
The particular pairs that get passed in depend on the sorting algorithm being used. As the algorithm tries to go about sorting the range, it needs to be able to compare pairs of values to determine their ordering. Whenever this happens, it will call your function to get that comparison.
Because of this, without inside knowledge about how the sorting algorithm works, you cannot predict what pairs will get compared. The choice of algorithm will directly determine what elements get compared and in what order.
Interestingly, though, you can actually use the comparison function to visualize how the sort works or to reverse-engineer the sorting algorithm! The website sortviz.org has many visualizations of sorting algorithms generated by passing custom comparators into sorting functions that track the positions of each element. If you take a look, you can see how differently each algorithm moves its elements around.
Even more interestingly, you can use comparison functions as offensive weapons! Some sorting algorithms, namely quicksort, have particular inputs that can cause them to run much more slowly than usual. In "A Killer Adversary for Quicksort," the author details how to use a custom comparator to deliberate construct a bad input for a sorting algorithm.
Hope this helps!
The two parameters will be elements of your array. The system will compare enough pairs to be able to sort them correctly. Nothing else is guaranteed.
There are lots of things the sort method could be doing under the hood; see, e.g., http://en.wikipedia.org/wiki/Sorting_algorithm for some of them. Most Javascript implementations probably use some variant of either quicksort or mergesort.
(Here are super-brief descriptions of those. Quicksort is: pick an element in the array, rearrange the array to put everything smaller than that in front of everything larger, then sort the "smaller" and "larger" bits. Mergesort is: sort the first half of the array, sort the second half of the array, and then merge the two sorted halves. In both cases you need to sort smaller arrays, which you do with the same algorithm until you get to arrays so small that sorting them is trivial. In both cases, good practical implementations do all sorts of clever things I haven't mentioned.)
It will be called for all pairs of a,b that sorting algorithm need to get all array sorted. Check out http://en.wikipedia.org/wiki/Sorting_algorithm for brief list of sorting algorithms.
When you pass a function to Array.sort(), it expects two parameters and returns a numerical value.
If you return a negative value, the first parameter will be placed before the second parameter in the array.
If you return a positive value, the first parameter will be placed after the second parameter in the array.
If you return 0, they will stay in their current position.
By doing return a - b;, you are returning a negative number if a is less than b (2 - 13 = -11), a positive number if b is less than a (13 - 2 = 11), and zero if they are even (13 - 13 = 0).
As far as which numbers are compared in what order, I believe that is up to the javascript engine to determine.
Check out the documentation on javascript array sorting at the MDC Doc Center for more detailed information.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort
(BTW, I always check the MDC Doc Center for any questions about how javascript works, they have the best information on the language AFAIK.)

Categories

Resources