how do I find the id of the minimum value of an array? - javascript

I know that you can have the minimum value of an array by typing
var min = Math.min.apply(null, array)
but this will return the smallest value of an array and not the id of this one
for exemple if I have these values:
array[1] = 24;
array[2] = 45;
I want it to return 1 (the ID holding the minimum value) but idk how to do, could someone help me with this issue please?

var index = array.indexOf(Math.min.apply(null, array));

You can use Array#reduce() to get the smallest number, while avoiding holes in the Array if needed.
array.reduce(function(obj, n, i) {
if (n < obj.min)
obj.i = i;
return obj;
}, {min:Infinity,i:-1}).i;
Or if performance and compatibility is a concern, you could just loop.
var res = -1;
var min = Infinity;
for (var i = 0; i < array.length; i++) {
if ((i in array) && array[i] < min) {
min = array[i];
res = i;
}
}

You can do it like this:
var id = array.indexOf(Math.min.apply(null, array));

Once you've got the value, you can use indexOf to get the index, like this:
var index = array.indexOf(Math.min.apply(null, array));
You should be aware that indexOf was only recently included in JavaScript (ES5/JS 1.6 to be precise) so you may want to find some wrapper for it if the function does not exist.
See the MDN for more information (which contains an example implementation of a backwards compatible function).

Just like the algorithm for finding the min value, but you have to track the minimum index as well
function minIndex(arr) {
if (!arr || arr.length === 0) {
return -1;
}
var min = arr[0];
var minIndex = 0;
for (var len = arr.length; len > 0; len--) {
if (arr[len] < min) {
min = arr[len];
minIndex = len;
}
}
return minIndex;
}
check out this fiddle

Related

How to stop random letter picking from doing duplicate letters [duplicate]

I need help with writing some code that will create a random number from an array of 12 numbers and print it 9 times without dupes. This has been tough for me to accomplish. Any ideas?
var nums = [1,2,3,4,5,6,7,8,9,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0 ; i < array.length; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
console.log(get_rand(nums));
}
The most effective and efficient way to do this is to shuffle your numbers then print the first nine of them. Use a good shuffle algorithm.What Thilo suggested will give you poor results. See here.
Edit
Here's a brief Knuth Shuffle algorithm example:
void shuffle(vector<int> nums)
{
for (int i = nums.size()-1; i >= 0; i--)
{
// this line is really shorthand, but gets the point across, I hope.
swap(nums[i],nums[rand()%i]);
}
}
Try this once:
//Here o is the array;
var testArr = [6, 7, 12, 15, 17, 20, 21];
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
shuffle(testArr);
This is relatively simple to do, the theory behind it is creating another array which keeps track of which elements of the array you have used.
var tempArray = new Array(12),i,r;
for (i=0;i<9;i++)
{
r = Math.floor(Math.random()*12); // Get a random index
if (tempArray[r] === undefined) // If the index hasn't been used yet
{
document.write(numberArray[r]); // Display it
tempArray[r] = true; // Flag it as have been used
}
else // Otherwise
{
i--; // Try again
}
}
Other methods include shuffling the array, removing used elements from the array, or moving used elements to the end of the array.
If I understand you correctly, you want to shuffle your array.
Loop a couple of times (length of array should do), and in every iteration, get two random array indexes and swap the two elements there. (Update: if you are really serious about this, this may not be the best algorithm).
You can then print the first nine array elements, which will be in random order and not repeat.
Here is a generic way of getting random numbers between min and max without duplicates:
function inArray(arr, el) {
for(var i = 0 ; i < arr.length; i++)
if(arr[i] == el) return true;
return false;
}
function getRandomIntNoDuplicates(min, max, DuplicateArr) {
var RandomInt = Math.floor(Math.random() * (max - min + 1)) + min;
if (DuplicateArr.length > (max-min) ) return false; // break endless recursion
if(!inArray(DuplicateArr, RandomInt)) {
DuplicateArr.push(RandomInt);
return RandomInt;
}
return getRandomIntNoDuplicates(min, max, DuplicateArr); //recurse
}
call with:
var duplicates =[];
for (var i = 1; i <= 6 ; i++) {
console.log(getRandomIntNoDuplicates(1,10,duplicates));
}
const nums = [1,2,3,4,5,6,7,8,9,10,11,12];
for(var i = 1 ; i < 10; i++){
result = nums[Math.floor(Math.random()*nums.length)];
const index = nums.indexOf(result);
nums.splice(index, 1);
console.log(i+' - '+result);
}

What's the problem with this implementation of selection sort?

I am learning selection sort.
I am getting the correct output for some values, but not for all the values, don't know why??
Please find below code snippet:
function selectionSortRecursion(arr,p){
if( arr.length === 1){
return p;
}
min=arr[0];
for(var i =0;i<arr.length;i++){
if (arr[i]<min){
min = arr[i];
var minIdx=i;
}
}
temp=arr[0];
arr[0]=arr[minIdx];
arr[minIdx]=temp;
p.push(arr.shift());
return selectionSortRecursion(arr,p);
}
console.log(selectionSortRecursion([2,3,5,-3,20,0,2,6,-23],[]));
The problem is that the variable minIdx is not declared unless the body of the if statement inside the loop is executed. If the minimum element is at index 0, then arr[i] < min is never true and minIdx is undefined.
To solve it, write var minIdx = 0; before the loop, since min is initialised as the value at index 0. A couple of your other variables should be declared with var, too:
function selectionSortRecursion(arr, p) {
if(arr.length === 0) {
return p;
}
var min = arr[0];
var minIdx = 0;
for(var i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
minIdx = i;
}
}
var temp = arr[0];
arr[0] = arr[minIdx];
arr[minIdx] = temp;
p.push(arr.shift());
return selectionSortRecursion(arr, p);
}
Note that I've also changed the loop variable i to start at 1, since there's no need to compare index 0 with itself; and the base case of the recursion should be when arr.length is 0, not 1, to avoid losing the last element.

returning only the first value of the largest element

I'm trying to return the largest element in the array. With strings this means the longest string. How do I return only the first instance of the largest element.
My code:
function getLongestElement(arr) {
var max = "";
var counter = 0;
for (var i = 0; i < arr.length; i++){
if (arr[i].length > counter) max = arr[i]
}
return max;
}
getLongestElement(['one', 'two', 'three', "thre1"]); // "thre1" not "three".
I'm not quite sure whats wrong with this code. No matter what the largest value is it only returns the last element in the array. Help?
counter is initialized to 0, but you never change its value so the if statement with arr[i].length > counter is always true (unless arr[i].length == 0). To fix it you need to keep track of the largest element of the array inside the loop:
// I renamed counter to maxLength for readability
function getLongestElement(arr) {
var max;
var maxLength = -1;
for (var i = 0; i < arr.length; i++){
if (arr[i].length > maxLength){
maxLength = arr[i].length;
max = i;
}
}
return arr[max];
}
First, good alghoritm should make no assumptions. That means your max shouldn't start from "", but using first array's element. You also don't edit your counter value, that's your main problem. But it is redundant and you can write this function without counter.
function getLongestElement(arr) {
if (arr.length < 1) return /* Some Exception */;
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i].length > max.length) max = arr[i];
}
return max;
}
You forgot to update counter
function getLongestElement(arr) {
var max = "";
var counter = 0;
for (var i = 0; i < arr.length; i++){
if (arr[i].length > counter) {
max = arr[i];
counter = max.length;
}
}
return max;
}
console.log(getLongestElement(['one', 'two', 'three', "thre1"])); // "thre1" not "three".
If you're looking for a pragmatic solution, I'd suggest lodash's _.maxBy:
_.maxBy(['one', 'two', 'three', "thre1"], function(str) {
return str.length;
})
If you're looking for a theoretical solution for the sake of learning,
function getLongestElement(arr) {
var max;
var counter = 0;
for (var i = 0; i < arr.length; i++){
if (arr[i].length > counter) max = arr[i]
counter = Math.max(arr[i].length, counter)
}
return max;
}
The key point here is to make sure you're updating the counter variable to whatever the currently longest length is.

Return a piece of an array after finding the highest integer in java script?

So after working on finding the highest sum of any given amount of credit card numbers I realized I dug myself into a bit of a hole. (currently using 3 cards "123-123, 234-234 and 345-345" as test numbers.) After writing this out:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for(var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace (/-/g, "");
for (var j = 0; j < eXt.length; j++) {
sum += parseInt(eXt.substr(j, 1));
}
sumpre.push(sum);
}
console.log(sumpre);
var highest = sumpre[0];
for (var i=1; i<=sumpre.length; i++){
if (sumpre[i]>highest){
highest=sumpre[i];
}
}
console.log(highest)
Which works to find the highest sum, however; I need it to return the card number with the highest sum in its original form at the end and am not sure what method would be best to get back to that or if I should reformat it from the start.
As I mentioned in a comment, or as shown in Gerardo's answer, one way to do it with minimal changes to your current code is to use highest to keep the index of the array item with the highest value, instead of keeping the actual value itself - then you could retrieve the original card value via that index.
But for fun, here's another way to do it:
function sumDigitsInString(s) {
return Array.prototype.reduce.call(s, function(p, c) { return p + (+c || 0); }, 0);
}
function itemWithLargestSum(a) {
return a.reduce(function(p, c) {
var sum = sumDigitsInString(c);
return p[0] > sum ? p : [sum, c];
}, [0])[1];
}
// given an array of strings:
var input = ["123-123", "234-234", "345-345", "111-111"];
var largest = itemWithLargestSum(input);
console.log(largest);
Further reading:
.call() method
Array .reduce()
Unary plus operator
|| operator
?: (ternary) operator
You could also do something like this, just with Array methods.
var inputCards = ["989-000", "123-999", "456-456"];
var sum = 0,
sumNumbers = {},
maxVal = 0;
inputCards.map(function(num) {
var replaceText = new RegExp(/-/g);
var number = num.replace(replaceText, "").split("");
var prevVal = 0;
sumNumbers[num] = number.reduce((prevVal, currentVal) =>
parseInt(prevVal, 10) + parseInt(currentVal, 10));
});
console.log(Object.keys(sumNumbers).reduce((maxVal, currentVal) =>
sumNumbers[maxVal] > sumNumbers[currentVal] ? maxVal : currentVal));

Javascript Difference of any number

i want to write a JavaScript function which finds the difference between the biggest and the smallest number. Input may be any number, so I use arguments.
I wrote a max and a min function, alone they are working fine. I have put them in a difference function to calculate max-min and return the result.
But there is a bug somewhere, the code is not running as expected.
<!DOCTYPE html>
<html>
<body>
<p>Finding the difference.</p>
<p id="demo"></p>
<script>
function difference() {
var diff = 0;
function findMax() {
var i, max = 0;
for(i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
function findMin() {
var i, min=Infinity;
for(i = 0; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
}
diff=max-min;
return diff;
}
document.getElementById("demo").innerHTML = difference(4, 5, 6,88);
</script>
</body>
</html>
Try this instead
function difference() {
var i, val = parseFloat(arguments[0]), min = val, max = val;
for(i = 1; i < arguments.length; i++) {
val = arguments[i];
min = Math.min(val, min);
max = Math.max(val, max);
}
return max - min;
}
no need for infinity either
You never call either findMin() or findMax().
You can use the builtins Math.min() or Math.max() instead, they both take an unlimited number of arguments so you can avoid iterating over the arguments yourself.
Like so:
function difference() {
var min = Math.min.apply(null, arguments),
max = Math.max.apply(null, arguments);
return max - min;
}
If for some reason you wish to make use of your existing findMin() and findMax() methods, you are only missing the invocation of these methods.
Inside difference(), you should do this:
var numbers = Array.slice(arguments); // create an array of args
var max = findMax.apply(this, numbers);
var min = findMin.apply(this, numbers);
return max - min;
And do fix your findMax() method as suggested by a comment if you wish to handle negative numbers.
You can do it in one for loop much easier:
var numbers = [4, 8, 1, 100, 50];
function difference(arr) {
var max = arr[0]
var min = arr[0];
for(var i = 0; i < arr.length; i += 1) {
if(arr[i] > max) {
max = arr[i];
}
if(arr[i] < min) {
min = arr[i];
}
}
var d = max - min;
return d;
}
var result = difference(numbers);
console.log(result);

Categories