Javascript Sub-Array - javascript

I recently ran into the problem where I would like to select multiple elements from an array, to return a sub-array. For example, given the array:
a = [1, 5, 1, 6, 2, 3, 7, 8, 3]
And the index array of:
i = [3, 5, 6]
I want to select all elements in a, who's index appears in i. So the output in my simple example would be:
[6, 3, 7]
I completely realise I could use a for loop over i and construct a new array then use Array.push(a[index (in i)]) to add in each, but I was wondering if there was a clearer/cleaner way to achieve this (possibly using underscore.js, or something similar).

i.map(function(x) { return a[x]; })
// => [6, 3, 7]

You can try this
a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
i = [3,5,6];
var res= []; //for show result array
for (var n in a){ //loop a[]
for(var index in i){ //loop i[]
if( n == i[index] ) //n is index of a[]
res.push(a[n]); //add array if equal n index and i[] value
}
}
alert(res); // 6,3,7

You could use map function to achieve your desired result.
var a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
var i = [3, 5, 6];
var mapped = i.map(function(index) {
return a[index];
});
console.log(mapped);
Here is the working jsfiddle.
However with above example, map not be available in all browsers yet. Here is the quote from documentation of map.
map was added to the ECMA-262 standard in the 5th edition; as such it
may not be present in all implementations of the standard.
If your code will be running in old browsers then you will need to add a polyfill. However there are libraries that give you similar functionality with polyfills for older browsers. Along with map function, underscodejs has tons of other helpful functions. I higly recommend you to look at what underscorejs has to offer. It provides tons of helper functions and has quite wide range browser support.
You would do following in underscorejs and wont have to worry if your code works in cross browsers.
var a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
var mapped = _.map([3, 5, 6], function(index) {
return a[index];
});
alert(mapped);
Here is jsfiddle for that.

Related

How to verify JavaScript memory consumption by a piece of code

both javascript code accomplish the same task merge the second array into the first one, i have read various blogs etc claming Option 2 is more memory efficient,
Is there a way or a tool to verify and see it for myself the memory usage in the Option 2 is lower ?
Option 1
//consume a lot of memory
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2));
Option 2
//reduce the memory usage
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2));
i tried this approach https://www.valentinog.com/blog/node-usage/ node js code, not much helpful
also tried https://github.com/paulirish/memory-stats.js dosent seems to work
Your premise is wrong. Both scripts do not accomplish the same task.
Your first option allocates a new result array with 6 elements, and leaves both array1 and array2 untouched. (See the documentation for Array.prototype.concat().)
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2)); // [1, 2, 3, 4, 5, 6]
console.log(array1); // [1, 2, 3]
console.log(array2); // [4, 5, 6]
Your second option merges the contents of array2 into array1. (See the documentation for Array.prototype.push().)
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2)); // 6
console.log(array1); // [1, 2, 3, 4, 5, 6]
console.log(array2); // [4, 5, 6]
So the second option only requires a total of 9 array elements, while the first option requires 12. On a language level, option 2 is 25% more memory-efficient. How much memory is actually used by the JavaScript engine you're using is an implementation detail. In addition, contrived examples like these are typically not good candidates for reliable performance testing as the engine's JavaScript interpreter might apply various optimizations.

what does max() function do in javascript if array has several equally large numbers

If we get something like
array=[5,5,5,5,3,2];
return Math.max.Apply(Math,array);
How do I get it to return the numbers from first to last if such a case occurs.
To answer the question in the title:
what does max() function do in javascript if array has several equally
large numbers
The answer is, nothing. Math.max() doesn't act on arrays.
You can pass an array by spreading the items as arguments to max():
Math.max(...[1,2,3]) // 3
Or as you've seen, with apply():
Math.max.apply(Math, [1,2,3]) // 3
If the question is more:
What does Math.max() do when more than one of the same maximum number is given?
The answer is, it returns that number:
const a = [5, 5, 5, 5, 3, 2]
const max = Math.max(...a)
console.log(max) // 5
This question is confusing:
How do I get it to return the numbers from first to last if such a case occurs.
You want it to return a sorted array? From [5, 5, 5, 5, 3, 2] to [2, 3, 5, 5, 5, 5]?
a.sort() // [2, 3, 5, 5, 5, 5]
You want dupes removed? From [5, 5, 5, 5, 3, 2] to [2, 3, 5]?
Array.from(new Set(a)) // [2, 3, 5]
Could you clarify your question?
The best way to do this is the following:
var a = [5,5,5,5,3,2];
var largest = Math.max.apply(null,a)
var filtered = a.filter(function(item) {
item === largest
});
Where filtered will have contain all the largest elements.
In #Clarkie's example, he's calling Math.max more frequently than needed.
In both Dan and Clarkie's example they're capitalizing Apply which is incorrect, the correct function to call is Math.max.apply and Math need not be passed in as the first argument.
See the following for a working example:
https://jsfiddle.net/fx5ut2mm/
Modifying #Clarkie's very nice idea. We can boil it down to...
var a = [5,5,5,5,3,2],
m = Math.max(...a),
f = a.filter(e => e == m);
document.write("<pre>" + JSON.stringify(f) + "</pre>");

Finding the lowest number in an array using split('') and reverse();

I am trying to find the min value of an array, and am trying to do it by sorting the array, and then reversing the array, and then calling the very first index of the array.
Unfortunately with what I have been trying, I keep getting 9. (don't know why) Can anybody take a quick look at what I have been doing and bail me out here? (i'm using js)
var minny = [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest = function (minny){
minny = minny.sort('');
var sorted = minny + " ";
sorted = minny.reverse('').join('');
return sorted[0];
}
console.log(smallest(minny))
By default the sort method sorts elements alphabetically(11 comes before 9) and therefore you need to add a compare function as a param.
var smallest = function (minny) {
minny = minny.sort(function(a, b) { return a - b; });
return minny[0];
}
console.log(smallest(minny))
JSFIDDLE.
Based on your code, you could just do
return minny.sort()[0];
So, your full code example becomes
var minny = [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest = function (minny){
return minny.sort()[0];
}
console.log(smallest(minny))
You're calling minny.sort('') which is using the default natural sort, so 11 and 25 end up near the beginning because of the 1 and 2.
What you have to do is call sort with a function that compares numbers, such as:
minny.sort(function(a,b) { return b-a; });
This will sort minny the way you want it.
There is no need to even call reverse and join afterwards, just return the first item. "return sorted[0]" is fine but will fail if there are no items, so you might just want to call "return sorted.shift()" instead. This will return the first item too, but won't fail if the array is empty.
PS. your call to minny.reverse also has an empty string as a parameter. That's not needed, reverse takes no parameters.
sort() sorts alphabetically by string representation, so in your case it would result in 1, 11, 2, 2, 25, .... You have to provide a comparison function for correct integer sorting, although in your specific case it doesn't really make a difference.
var smallest = function (minny){
minny = minny.sort(function(a, b){return a-b});
return minny[0];
}
See jsfiddle
Using sort is fairly short code to write, and it will return the correct number if you use minny.sort(function(a,b){return a-b})[0].
If you have a large unordered array you are running the comparison many times and you are sorting the array, which is not usually what you want to do to an array.
It may be better to just iterate the members and compare each just once to the lowest fond so far.
var minny= [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest= function(minny){
var min= Infinity;
minny.forEach(function(next){
if(next<min) min= next;
});
return min;
}
Or use Math.min, if this is code golf:
Math.min.apply(Array,minny);

Pick random and remove from collection using underscore

I've got a collection of 20 results (objects), and what I'd like to do when a button is clicked is to:
a) Pick a random object from this collection/array
b) When the button is pressed again - I don't want that object re-picked until the collection is exhausted (i.e. until the 20 items are shown)
I thought of just splicing out the index of that collection, but I'm hoping for a cleaner way using Underscore.js
EXAMPLE:
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11...]
var getRand = _.random(0, data.length);
==> 3
Next time I press the button, I don't want the result "3" to re-appear as it's been used
I hope this makes sense
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
// cache indexes
var cache = _.map(new Array(data.length + 1).join(), function (item, index) {
return index;
});
// get random from cached array
var rand = _.random(0, cache.length);
// remove random index from cache
cache.splice(rand, 1);
console.log(rand, cache)
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
var picked = [];
$("#link").click(function() {
if(data.length == 0) return;
var pick = data.splice(_.random(0,data.length),1);
picked.push(pick);
$("#pick").html(pick);
$("#data").html(data.join(","));
$("#picked").html(picked.join(","));
});
http://jsfiddle.net/Z3vjk/
You could make an array to store the values you've used and check all new random numbers to see if they appear. This would get messy near the end of the array though as the random number generator tries to guess a single number.
If it were me I would just what you alluded to and take the elements out as you use them and place them into a temporary array. Once all elements are used, reassign the temp array to the original variable name.

Auto-formatting Javascript arrays into new lines in Aptana Studio 3

It seems that Aptana Studio 3 only has the option for auto-formatting Javascript arrays into one line. I was wondering if there is a way to make Aptana Studio 3 auto-format Javascript arrays into a new line for each array element (similar to the option for auto-formatting php arrays - "Insert new line between array creation elements").
For example, I want
var dataset = [1, 2, 3, 4];
to become
var dataset = [1,
2,
3,
4];
What I usually do in Aptana is this:
var dataset = [
//
1,
//
2,
//
3,
//
4
//
];
And Aptana is dumb enough to be smart about not trying to interpolate with line comments.
Then you can even have:
var dataset = [
//
[1, 3, 5, 7, 9],
//
[2, 4, 6, 8, 0],
//
'Some string here',
//
function( ) {
return 'even a function';
}
//
];
try this,
var dataset = [1,//
2,//
3,//
4];
Aptana doesnt put it in one line, if its followed by a comment.

Categories

Resources