JS - Thin number of points based on density - javascript

Say I have an array as follows (each small array is [x, y]):
var myPoints = [[25, 28], [26, 26], [70, 40], [50, 50], [300, 300], [285, 350], [1000, 1000]];
Let's say I need to thin the array down to 4 points. (this is a small example, my acutal array has thousands of points) How could I go about thinning the array based on density so more points are removed from areas with points closer together and less points are removed from areas with lower density?
In this case (reducing the above array from 8 to 4 items) I would expect the returned array to look something like the following:
var thinnedPoints = [[25, 28], [70, 40], [300, 300], [1000, 1000]];
My idea on how to approach this would be to generate a dictionary that maps the point to it's minimum distance to another point (e.g. a point close to another point would have a small minimum distance) then sort the dictionary based on ascending minimum distance, then remove every n'tn item of the dictionary.
The problem with this approach is I don't know how to efficiently generate the distance to closest other point value for each point.
Is there an efficient way to generate those values or maybe is there another way to approach this density based thinning problem?
Thanks!

It seems you want to solve either a P-center problem or a P-median problem.
From Approximability Results for the p-Center Problem by Stefan Buettcher,
The p-Center problem, also known as the Min-Max Multicenter problem
or the Facility Location problem, is a famous problem from operations
research. Informally, it is the problem of placing fire stations in a
city so that the maximum time to reach any point in the city is
minimized.
From Methods for Solving the p-Median Problem: An Annotated Bibliography by J. Reese,
The p-median problem is simply stated as: Given a graph or a network
G = (V, E), find Vp ⊆ V such that |Vp| = p, where p may either
be variable or fixed [...], and that the sum of the shortest distances
from the vertices in {V\Vp} to their nearest vertex in Vp is
minimized.
Both problems are NP-complete in general, so there is no (known) way to solve them in polynomial time. But there are various heuristics you could try.

A very simple and efficent solution that works especially well on large sets is to just pick the points randomly. This implicitly removes less points from regions containing less points than elsewhere - which seems to be just what you want, if you only want to scale the density linearly. It should yield the same results as your approach, without needing to calculate any distances.
If the data is not ordered in any way (i.e. already random), you can also drop every second point or just the first or second half.
If you want to tweak the density distribution non-linearly, you could divide the set into multiple regions (e.g. squares) small enough so that the density is roughly uniform in each of them, and then drop every n-th of the points per region. If you choose the region size appropriately, this approach might also deliver better (and more consisten) results than the purely random one on smaller data sets.

You can use for..of loop, for loop, .map(), Math.min(), .filter().
Loop through each element of array, assign x, y to separate array variables; subtract the difference between each element in x or y arrays; map original array, begin by removing first or second element of matched pair where the two elements have the least numeric difference between any other number in array; that is, the two numbers are separated by the least amount of digits. Continue removing elements, as distance between numbers increases, until n, here, 3, elements are removed from original array.
For example, mapping x can return either
[[25, 28], [70, 40], [300, 300], [1000, 1000]];
or
[[26,26], [50,50], [285,350], [1000,1000]]
as the range between the numbers is the same each in direction
[1, 1, 20, 20, 15, 15, 700]
var myPoints = [
[25, 28],
[26, 26],
[70, 40],
[50, 50],
[300, 300],
[285, 350],
[1000, 1000]
];
var [x, y] = [
[],
[]
];
var [xx, yy] = [
[],
[]
];
for (let z of myPoints) {
[x, y] = [
[...x, z[0]],
[...y, z[1]]
];
}
var stop = 3;
for (var i = 0; i < x.length; i++) {
var prop = x[i];
if (typeof xx[i] !== "object") {
xx[i] = {
index: i,
diff: [],
value: prop
};
}
for (var len = 0; len < x.length; len++) {
var key = x[len];
xx[i].diff.push(
prop > key
? prop - key
: key > prop ? key - prop : Infinity
)
}
}
var range = xx.map(prop => Math.min.apply(Math, prop.diff));
var temp = range.slice(0);
for (var i = 0; i < stop; i++) {
var curr = Math.min.apply(Math, temp);
var index = temp.indexOf(curr);
temp[index] = Infinity;
var pair = Math.min.apply(Math, temp);
var next = temp.indexOf(pair);
temp[next] = Infinity;
x[next] = void 0;
};
var res = myPoints.map((prop, index) =>
x[index] === undefined ? null : prop).filter(Boolean);
console.log(res);
usage as a function
var myPoints = [
[25, 28],
[26, 26],
[70, 40],
[50, 50],
[300, 300],
[285, 350],
[1000, 1000]
];
var filter = (arr, xy, n) => {
var [x, y] = [
[],
[]
];
var [xx, yy] = [
[],
[]
];
for (let z of arr) {
[x, y] = [
[...x, z[0]],
[...y, z[1]]
];
}
var XY = {
"x": [x, xx],
"y": [y, yy]
};
var item = XY[xy];
var stop = n;
for (var i = 0; i < item[0].length; i++) {
var prop = item[0][i];
if (!item[1][i]) {
item[1][i] = {
index: i,
diff: [],
value: prop
};
}
for (var len = 0; len < item[0].length; len++) {
var key = item[0][len];
item[1][i].diff.push(
prop > key ? prop - key : key > prop ? key - prop : Infinity
)
}
}
var range = item[1].map(prop => Math.min.apply(Math, prop.diff));
var temp = range.slice(0);
for (var i = 0; i < stop; i++) {
var curr = Math.min.apply(Math, temp);
var index = temp.indexOf(curr);
temp[index] = Infinity;
var pair = Math.min.apply(Math, temp);
var next = temp.indexOf(pair);
temp[next] = Infinity;
item[0][next] = void 0;
};
return arr.map((prop, index) =>
item[0][index] === undefined ? null : prop).filter(Boolean);
}
console.log(filter(myPoints, "x", 3));

Related

Sorting an array while iterating by two?

I'm optimizing an algorithm that generates a texture for my game.. long story
Anyway, while profiling I found I could shave off an extra 10% off the runtime if I could eliminate converting vertex data from one format to another. Essentially, all vertex data comes in a single array like so: [x0, y0, x1, y1, ... xn, yn]
I need to sort the vertices first by X and then by Y. So far I've achieved this by converting the vertex data into an array of arrays like so: [[x0, y0], [x1, y1], ... [xn, yn]]
And then using Array.sort((a, b) => a[0] > b[0] ? -1 : a[0] < b[0] ? 1 : 0) and switching the index to sort by Y later and then convert back into the original format.
All this converting takes unnecessary time. Is it possible to somehow make Array.sort() iterate by two instead or some equivalent?
Other than that, I've also thought about implementing my own sort function. What are my odds of competing with the native Array.sort() performance wise?
You could take a sorting of the indices and build a new array based in the indices.
var data = [0, 1, 3, 2, 1, 5, 1, 4, 2, 3, 4, 2],
indices = [],
result = [];
for (let i = 0; i < data.length; i += 2) indices.push(i);
indices.sort((a, b) => data[a] - data[b]);
for (let i of indices) result.push(data[i], data[i + 1]);
console.log(result);
Just for fun though because I don't believe this is gonna be faster that your existing solution - you can use proxy and iterators to make Array-like object which returns every second member:
var input = [500,400,300,200,100];
var proxy = new Proxy(input, {
get(target, name) {
if (name === 'length') {
return Math.ceil(target.length / 2);
}
if (name === Symbol.iterator) {
return function*() {
for (let i = 0; i < target.length; i += 2)
yield target[i];
}
}
if (Array.prototype.hasOwnProperty(name)) {
return target[name];
}
return target[name * 2];
},
set(target, name, value) {
target[name * 2] = value;
return true;
}
});
console.log([...proxy]); // [500, 300, 100]
proxy.sort((x, y) => x - y);
console.log(input); // [100, 400, 300, 200, 500]
console.log([...proxy]); // [100, 300, 500]

How to extract values with the same key from array and compute their average?

so I have a few arrays for different datasets that look similair to this one:
[["zufrieden",10],
["beschämt",24],
["gelangweilt",50],
["begeistert",28],
["unsicher",27],
["niedergeschlagen",49],
["verärgert",72],
["frustriert",29],
["entspannt",25],
["unsicher",27],
["unsicher",31],
["schuldig",22],
["frustriert",18],
["gelangweilt",73],
["wütend",30],
["verlegen",50],
["besorgt",25],
["schwermütig",0]]
How can i get, for example, the average value of all entries with "schuldig".
Also, I need to do this for every single key that is represented by a string in this case.
I tried converting the array to an object and go from there, but I'm stuck and would appreciate any help.
I already came as far counting the occurences of the different strings using the map function.
var counts = {};
orderedFeelings.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
var countsValues = Object.keys(counts).map(function(key){ return counts[key] });
This is okay for my intent to visualize the data as it returns a list of the occurences, but in order to create a detailed graph, I need to have the average value of all values with the same keys. This is where I'm completely stuck.
All information in one object, with just one iteration O(n):
var arr = [
["zufrieden", 10],
["beschämt", 24],
["gelangweilt", 50],
["begeistert", 28],
["unsicher", 27],
["niedergeschlagen", 49],
["verärgert", 72],
["frustriert", 29],
["entspannt", 25],
["unsicher", 27],
["unsicher", 31],
["schuldig", 22],
["frustriert", 18],
["gelangweilt", 73],
["wütend", 30],
["verlegen", 50],
["besorgt", 25],
["schwermütig", 0]
]
var average = {}
arr.map(o => {
if (o[0] in average) {
average[o[0]][0] += o[1]
average[o[0]][1]++
average[o[0]][2] = average[o[0]][0] / average[o[0]][1]
} else {
average[o[0]] = []
average[o[0]].push(o[1]);//<-- Name
average[o[0]].push(1);//<-- Quantity
average[o[0]].push(o[1] / 1);//<-- Average
}
})
console.log(average.schuldig[2])//<-- Average
console.log(average)
The key is always calculate the average, at the end, we have the real average.
you can use filter method of array
const newArray = this.array.filter(temp => temp[0] === 'schuldig');
var total = 0;
for (each of newArray) {
total += each[1];
}
const avg = (total/newArray.length);
This will give you average the wayx you need it
If you have a predefined format of your dataset like at the first index of each array will be the text and at the second index of array will be the value then you can compute the average by this
function computeAvg(dataset,key) {
let desiredElements = dataset.filter(item => item[0] === key);
return (desiredElements.reduce((sum, current) => sum + current[1],0))/desiredElements.length;
}
let dataset = [["zufrieden",10],
["beschämt",24],
["gelangweilt",50],
["begeistert",28],
["unsicher",27],
["niedergeschlagen",49],
["verärgert",72],
["frustriert",29],
["entspannt",25],
["unsicher",27],
["unsicher",31],
["schuldig",22],
["frustriert",18],
["gelangweilt",73],
["wütend",30],
["verlegen",50],
["besorgt",25],
["schwermütig",0]];
let average = computeAvg(dataset,'schuldig');
You can group all the entries by key with Array.prototype.reduce while counting total sum and their amount, and then go through grouped object and calculate averages:
var data=[["zufrieden",10],["beschämt",24],["gelangweilt",50],["begeistert",28],["unsicher",27],["niedergeschlagen",49],["verärgert",72],["frustriert",29],["entspannt",25],["unsicher",27],["unsicher",31],["schuldig",22],["frustriert",18],["gelangweilt",73],["wütend",30],["verlegen",50],["besorgt",25],["schwermütig",0]];
var grouped = data.reduce((all, [key, val]) => {
if (!all[key]) all[key] = {sum: 0, count:0}
all[key].count++;
all[key].sum += val;
return all;
},{});
var averages = Object.keys(grouped).reduce((all, k) => {
all[k] = parseInt(grouped[k].sum / grouped[k].count);
return all;
}, {});
console.log(averages.zufrieden);
console.log(averages.unsicher);
loop through your data, use array's filter function and compare your current object's [0] index with filters object's [0] index. Now you have matched elements, now use array's reduce method to calculate sum for current key i.e 'zufrieden' and then divide its value by the length of matched array and push that value in current iteration of outer loop i.e 'x'
const data = [
["zufrieden", 10],
["beschämt", 24],
["gelangweilt", 50],
["begeistert", 28],
["unsicher", 27],
["niedergeschlagen", 49],
["verärgert", 72],
["frustriert", 29],
["entspannt", 25],
["unsicher", 27],
["unsicher", 31],
["schuldig", 22],
["frustriert", 18],
["gelangweilt", 73],
["wütend", 30],
["verlegen", 50],
["besorgt", 25],
["schwermütig", 0]
];
/*
loop through your data, use array's filter function and compare your current object's [0] index with filters object's [0] index. Now you have matched elements, now use array's reduce method to calculate sum for current key i.e 'zufrieden' and then divide its value by the length of matched array and push that value in current iteration of outer loop i.e 'x'
*/
data.forEach(x => {
const matched = data.filter(y => y[0] == x[0]);
x.push(matched.map(z => z[1]).reduce((a, b) => a + b, 0) / matched.length);
});
console.log(data);

Convert a range of numbers to portion of 100

I have a list of numbers (any length) ranging from 0 - 100, including duplicates. I need convert those numbers to portions of 100.
For example:
[25, 50] becomes [33.333, 66.666]
[25, 50, 50] becomes [20, 40, 40]
What algorithm would work best for this?
You would need to calculate the sum of the values in your array - then you could divide each value in your array by that sum, and multiply by 100.
Try this :
console.log(33.333 - 33.333 % 25); // 50
% is MODULO operator.
Number.prototype.range = function(a) {
return this - this % a;
}
console.log((33.333).range(25)); // 25;
console.log((66.666).range(25)); // 50;
In array use map like this :
console.log([33.333, 66.666].map(function(a) {
return a.range(25);
}));
Demo
This can be done by calculating the sum of the array and then dividing each value by that. It can be done easily using Array.reduce to sum and Array.map to create a new array with the final output. Here is an example:
var arr1 = [25, 50];
var arr2 = [25, 50, 50];
function proportion(arr) {
var sum = arr.reduce(function(prev, cur){
return prev + cur;
});
var result = arr.map(function(val){
return (val/sum)*100;
});
return result;
}
console.log(proportion(arr1)); // [33.33333333333333, 66.66666666666666]
console.log(proportion(arr2)); // [20, 40, 40]
JSBin here: http://jsbin.com/texuc/1/edit
The simplest way to solve this is to sum the array, find each value as a fraction of that sum, and then multiply by 100.
This code should do the trick.
var inputArray = [25, 50, 50];
var outputArray = [];
var total = 0;
for (var i=0; i<(inputArray.length); i++) {
total += inputArray[i];
}
for (var i=0; i<(inputArray.length); i++) {
outputArray[i] = ((inputArray[i])/total) * 100;
}

How can I find all indexes of the max value of an array in javascript?

I am trying to find a way to get the max value of an array, then find all indexes of that value. I want to repeat this two more times.
I have an array of 8 scores. I want to find all first places, all second places, and all third places.
Array = [0, 400, 300, 400, 300, 200, 100, 200]
1st place indexes: 1, 3
2nd place indexes: 2, 4
3rd place indexes: 5, 7
How can I achieve this in javascript?
The following code does the trick:
var scores = [0, 400, 300, 400, 300, 200, 100, 200];
// make a working copy, so that we can change the working copy
// while doing the calculations without changing the original array
var working = scores.slice(0),
max,
indices,
numberOfPlaces = 3,
results = [];
for (var p = 0; p < numberOfPlaces; p++) {
max = Math.max.apply(null, working);
indices = [];
for (var i = 0; i < working.length; i++)
if (working[i] === max && working[i] > Number.NEGATIVE_INFINITY) {
indices.push(i);
working[i] = Number.NEGATIVE_INFINITY;
}
results.push(indices);
}
For your input results will be [[1,3], [2,4], [5,7]]. That is, results[0] will hold the first place indices, results[1] will hold the second place indices, and so on.
If you later decided you only wanted the first two places, or your wanted the first five, just change the numberOfPlaces variable.
Assuming the scores are not big numbers, you can build a hash of "score to indexes", and then sort by keys, and print out the indexes:
the running sample:
http://jsfiddle.net/nmA35/2/
the code:
var arr = [0, 400, 300, 400, 300, 200, 100, 200];
var hashValueToPosition = {};
var i;
for (i = 0; i < arr.length; i++) {
hashValueToPosition[arr[i]] = (hashValueToPosition[arr[i]] || []);
hashValueToPosition[arr[i]].push(i);
}
// see http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object for Object.keys or the following:
var getKeys = function(obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
var arrMaxToMinScores = getKeys(hashValueToPosition).sort().reverse();
for (i = 0; i < arrMaxToMinScores.length; i++) {
$("body").append("<pre>" + arrMaxToMinScores[i] + ": " + JSON.stringify(hashValueToPosition[arrMaxToMinScores[i]]) + "</pre>");
}
function awardPrizes(arr){
var L= arr.length, prizes= [[], [], []], n;
// save the three highest scores in scores array:
// eg: [400,300,200]
var scores= arr.slice().filter(function(n, i){
return arr.indexOf(n)== i;
}).sort(function(a, b){ return b-a}).slice(0, 3);
//put the high scoring indexes in the relevant prizes array:
arr.forEach(function(itm, i){
n= scores.indexOf(itm);
if(n!= -1) prizes[n].push(i);
});
return prizes;
//[first group,second group,third group]
}
var data= awardPrizes([0, 400, 300, 400, 300, 200, 100, 200]);
/* returned value: (Array)
[
[1, 3],
[2, 4],
[5, 7]
]
*/
Like functional programming?
a={};[0, 400, 300, 400, 300, 200, 100, 200].forEach(
(el,i) => a[el]? a[el].push(i) : a[el]=[i]
);
Object.keys(a).sort().reverse().map(k => [Number(k),a[k].sort()])
Basically hashes all the values, then goes through the keys in descending order, mentioning the indexes in ascending order. Ex:
[
[400,[1,3]],
[300,[2,4]],
[200,[5,7]],
[100,[6]],
[0,[0]]
]

Obtain smallest value from array in Javascript?

Array justPrices has values such as:
[0] = 1.5
[1] = 4.5
[2] = 9.9.
How do I return the smallest value in the array?
The tersest expressive code to find the minimum value is probably rest parameters:
const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
const min = Math.min(...arr)
console.log(min)
Rest parameters are essentially a convenient shorthand for Function.prototype.apply when you don't need to change the function's context:
var arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
var min = Math.min.apply(Math, arr)
console.log(min)
This is also a great use case for Array.prototype.reduce:
const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
const min = arr.reduce((a, b) => Math.min(a, b))
console.log(min)
It may be tempting to pass Math.min directly to reduce, however the callback receives additional parameters:
callback (accumulator, currentValue, currentIndex, array)
In this particular case it may be a bit verbose. reduce is particularly useful when you have a collection of complex data that you want to aggregate into a single value:
const arr = [{name: 'Location 1', distance: 14}, {name: 'Location 2', distance: 58}, {name: 'Location 3', distance: 20}, {name: 'Location 4', distance: 77}, {name: 'Location 5', distance: 66}, {name: 'Location 6', distance: 82}, {name: 'Location 7', distance: 42}, {name: 'Location 8', distance: 67}, {name: 'Location 9', distance: 42}, {name: 'Location 10', distance: 4}]
const closest = arr.reduce(
(acc, loc) =>
acc.distance < loc.distance
? acc
: loc
)
console.log(closest)
And of course you can always use classic iteration:
var arr,
i,
l,
min
arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
min = Number.POSITIVE_INFINITY
for (i = 0, l = arr.length; i < l; i++) {
min = Math.min(min, arr[i])
}
console.log(min)
...but even classic iteration can get a modern makeover:
const arr = [14, 58, 20, 77, 66, 82, 42, 67, 42, 4]
let min = Number.POSITIVE_INFINITY
for (const value of arr) {
min = Math.min(min, value)
}
console.log(min)
Jon Resig illustrated in this article how this could be achieved by extending the Array prototype and invoking the underlying Math.min method which unfortunately doesn't take an array but a variable number of arguments:
Array.min = function( array ){
return Math.min.apply( Math, array );
};
and then:
var minimum = Array.min(array);
I find that the easiest way to return the smallest value of an array is to use the Spread Operator on Math.min() function.
return Math.min(...justPrices);
//returns 1.5 on example given
The page on MDN helps to understand it better: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min
A little extra:
This also works on Math.max() function
return Math.max(...justPrices);
//returns 9.9 on example given.
Hope this helps!
Update: use Darin's / John Resig answer, just keep in mind that you dont need to specifiy thisArg for min, so Math.min.apply(null, arr) will work just fine.
or you can just sort the array and get value #1:
[2,6,7,4,1].sort()[0]
[!] But without supplying custom number sorting function, this will only work in one, very limited case: positive numbers less than 10. See how it would break:
var a = ['', -0.1, -2, -Infinity, Infinity, 0, 0.01, 2, 2.0, 2.01, 11, 1, 1e-10, NaN];
// correct:
a.sort( function (a,b) { return a === b ? 0 : a < b ? -1: 1} );
//Array [NaN, -Infinity, -2, -0.1, 0, "", 1e-10, 0.01, 1, 2, 2, 2.01, 11, Infinity]
// incorrect:
a.sort();
//Array ["", -0.1, -2, -Infinity, 0, 0.01, 1, 11, 1e-10, 2, 2, 2.01, Infinity, NaN]
And, also, array is changed in-place, which might not be what you want.
Imagine you have this array:
var arr = [1, 2, 3];
ES6 way:
var min = Math.min(...arr); //min=1
ES5 way:
var min = Math.min.apply(null, arr); //min=1
If you using D3.js, there is a handy function which does the same, but will ignore undefined values and also check the natural order:
d3.max(array[, accessor])
Returns the maximum value in the given array using natural order. If
the array is empty, returns undefined. An optional accessor function
may be specified, which is equivalent to calling array.map(accessor)
before computing the maximum value.
Unlike the built-in Math.max, this method ignores undefined values;
this is useful for ignoring missing data. In addition, elements are
compared using natural order rather than numeric order. For example,
the maximum of the strings [“20”, “3”] is “3”, while the maximum of
the numbers [20, 3] is 20.
And this is the source code for D3 v4:
export default function(values, valueof) {
var n = values.length,
i = -1,
value,
max;
if (valueof == null) {
while (++i < n) { // Find the first comparable value.
if ((value = values[i]) != null && value >= value) {
max = value;
while (++i < n) { // Compare the remaining values.
if ((value = values[i]) != null && value > max) {
max = value;
}
}
}
}
}
else {
while (++i < n) { // Find the first comparable value.
if ((value = valueof(values[i], i, values)) != null && value >= value) {
max = value;
while (++i < n) { // Compare the remaining values.
if ((value = valueof(values[i], i, values)) != null && value > max) {
max = value;
}
}
}
}
}
return max;
}
ES6 is the way of the future.
arr.reduce((a, b) => Math.min(a, b));
I prefer this form because it's easily generalized for other use cases
var array =[2,3,1,9,8];
var minvalue = array[0];
for (var i = 0; i < array.length; i++) {
if(array[i]<minvalue)
{
minvalue = array[i];
}
}
console.log(minvalue);
Possibly an easier way?
Let's say justPrices is mixed up in terms of value, so you don't know where the smallest value is.
justPrices[0] = 4.5
justPrices[1] = 9.9
justPrices[2] = 1.5
Use sort.
justPrices.sort();
It would then put them in order for you. (Can also be done alphabetically.) The array then would be put in ascending order.
justPrices[0] = 1.5
justPrices[1] = 4.5
justPrices[2] = 9.9
You can then easily grab by the first index.
justPrices[0]
I find this is a bit more useful than what's proposed above because what if you need the lowest 3 numbers as an example? You can also switch which order they're arranged, more info at http://www.w3schools.com/jsref/jsref_sort.asp
function smallest(){
if(arguments[0] instanceof Array)
arguments = arguments[0];
return Math.min.apply( Math, arguments );
}
function largest(){
if(arguments[0] instanceof Array)
arguments = arguments[0];
return Math.max.apply( Math, arguments );
}
var min = smallest(10, 11, 12, 13);
var max = largest([10, 11, 12, 13]);
console.log("Smallest: "+ min +", Largest: "+ max);
I think I have an easy-to-understand solution for this, using only the basics of javaScript.
function myFunction() {
var i = 0;
var smallestNumber = justPrices[0];
for(i = 0; i < justPrices.length; i++) {
if(justPrices[i] < smallestNumber) {
smallestNumber = justPrices[i];
}
}
return smallestNumber;
}
The variable smallestNumber is set to the first element of justPrices, and the for loop loops through the array (I'm just assuming that you know how a for loop works; if not, look it up). If an element of the array is smaller than the current smallestNumber (which at first is the first element), it will replace it's value. When the whole array has gone through the loop, smallestNumber will contain the smallest number in the array.
Here’s a variant of Darin Dimitrov’s answer that doesn’t modify the Array prototype:
const applyToArray = (func, array) => func.apply(Math, array)
applyToArray(Math.min, [1,2,3,4]) // 1
applyToArray(Math.max, [1,2,3,4]) // 4
function tinyFriends() {
let myFriends = ["Mukit", "Ali", "Umor", "sabbir"]
let smallestFridend = myFriends[0];
for (i = 0; i < myFriends.length; i++) {
if (myFriends[i] < smallestFridend) {
smallestFridend = myFriends[i];
}
}
return smallestFridend
}
A super-easy way to find the smallest value would be
Array.prototype.min = function(){
return Math.min.apply(Math,this);
};
To call the function, just use the name of the array and add .min()
Array.prototype.min = function(){
return Math.min.apply(Math,this);
};
var arr = [12,56,126,-1,5,15];
console.log( arr.min() );
If you are using Underscore or Lodash you can get the minimal value using this kind of simple functional pipeline
_.chain([7, 6, -1, 3, 2]).sortBy().first().value()
// -1
You also have the .min function
_.min([7, 6, -1, 3, 2])
// -1
Here is code that will detect the lowest value in an array of numbers.
//function for finding smallest value in an array
function arrayMin(array){
var min = array[0];
for(var i = 0; i < array.length; i++){
if(min < array[i]){
min = min;
}else if (min > array[i]){
min = array[i + 1];
}else if (min == array[i]){
min = min;
}
}
return min;
};
call it in this way:
var fooArray = [1,10,5,2];
var foo = arrayMin(fooArray);
(Just change the second else if result from: min = min to min = array[i]
if you want numbers which reach the smallest value to replace the original number.)
Here is a recursive way on how to do it using ternary operators both for the recursion and decision whether you came across a min number or not.
const findMin = (arr, min, i) => arr.length === i ? min :
findMin(arr, min = arr[i] < min ? arr[i] : min, ++i)
Code snippet:
const findMin = (arr, min, i) => arr.length === i ? min :
findMin(arr, min = arr[i] < min ? arr[i] : min, ++i)
const arr = [5, 34, 2, 1, 6, 7, 9, 3];
const min = findMin(arr, arr[0], 0)
console.log(min);
You can use min method in Math object!
const abc = [50, 35, -25, -6, 91];
function findMin(args) {
return Math.min(...args);
}
console.log(findMin(abc));
For anyone out there who needs this I just have a feeling.
(Get the smallest number with multi values in the array)
Thanks to Akexis answer.
if you have let's say an array of
Distance and ID and ETA in minutes
So you do push maybe in for loop or something
Distances.push([1.3, 1, 2]); // Array inside an array.
And then when It finishes, do a sort
Distances.sort();
So this will sort upon the first thing which is Distance here.
Now we have the closest or the least is the first you can do
Distances[0] // The closest distance or the smallest number of distance. (array).

Categories