I have two functions, they do look alike but what I don't really understand is when inside the for-loop, since the input is an array, why doesn't the array need any index to call the first array?
I have an array of...
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
I'm trying to loop through the array with an input. The result of the first function will then be used as the next function's input then the first array will be removed.
This is what I wrote...
function applyAndEmpty(input, queue)
{
var length = queue.length;
for(var i = 0; i < length; i++)
{
input = queue[0](input);
queue.shift();
}
return input;
}
The above does give me the answer but then I see that there's another way of writing it which is
var applyAndEmpty = function(input, queue)
{
var length = queue.length;
for(var i = 0; i < length; i++)
{
input = queue.shift()(input);
}
return input;
};
What I don't understand is the part input = queue.shift()(input).
Doesn't the queue need an index?
So you're basically asking what shift does and here you go:
What you can do using for(var i=0;... you can do using shift() (quite similar but not!)
Using for loop (and index)
var array = [
function(){return "a";},
function(){return "b";}
];
for(var i=0; i<array.length; i++){
console.log( array[i]() );
// "a"
// "b"
}
console.log(array.length); //2 !!Still there!!!
Using shift() (and while for example)
var array = [
function(){return "a";},
function(){return "b";}
];
while(array.length){ // while array has length
console.log( array.shift()() ); // execute and remove from array
// "a"
// "b"
}
console.log(array.length); //0 !!!Empty array due to shift()!!!
So basically it removes a key from your Array and returns it.
As long as that array has keys it will loop until it's empty.
The difference between the two is drastic:
The for loop in example 1. will loop but not alter your original array.
Using shift() in example 2. you're (using and) removing your Array keys one by one.
Read more about Array manipulation:
Array.prototype.shift 1 <-- [2,3,4]
Array.prototype.unshift 5 --> [5,2,3,4]
Array.prototype.push [5,2,3,4,6] <-- 6
Array.prototype.pop [5,2,3,4] --> 6
and other Methods
You can simplify the logic using Array.reduce
Here how you can do that:
var puzzlers = [
function(a) { return 8 * a - 10; },
function(a) { return (a - 3) * (a - 3) * (a - 3); },
function(a) { return a * a + 4; },
function(a) { return a % 5; }
];
function runPuzzler(inputValue){
return puzzlers.reduce(function(prev, curr){
return curr(prev);
},inputValue);
}
Output :
EachArrayValues::100
EachArrayValues::200
EachArrayValues::0
EachArrayValues::400
EachArrayValues::500
EachArrayValues::-50
Negative value found, ie -50
Related
...
function ar(farray) {
var array = farray.slice(0, 2);
for (i = 2; i <= farray.length; i++) {
if (array[0] < farray[i]) {
//Here is the problem.Why i can 't just (re)assign value, referencing to another array?
//need to be assigned-copied-rewrited!!
array[0] = farray[i];
}
}
return array[0] + array[1];
}
Create a function that returns the sum of the two lowest positive numbers given an array of minimum 4 integers. No floats or empty arrays will be passed.
function sumTwoSmallestNumbers(numbers) {
var array=numbers.slice(0,2);
array.sort(function(a,b){return b-a});
array[0]=numbers[0];
array[1]=numbers[1];
for (i=2;i<=numbers.length; i++){
if (numbers[i]<array[0] || numbers[i]<array[1]) {
if (numbers[i]<array[0]) {
array[0]=numbers[i];
} else {
array[1]=numbers[i];
}
}
Solved!
//My sorting relies on positions of value in 'array', therefore for every 'for' loop I need prepared positions
array.sort(function(a,b){return b-a});
}
return array[0]+array[1];
};
why you need another array ?
function ar(farray) {
var a = farray[0];
for (i = 2; i <= farray.length; i++) {
if (a < farray[i])
a = farray[i];
}
return a + farray[1];
}
Here is my code:
function iLoveThree (array) {
var threes = [];
var x;
for (x in array) {
if (x % 3 == 0) {
threes.push(x)
}
}
return threes
}
When I pass the array [1,2,3,4,5,6,7,8,9] I get the following:
Function returned
["0","3","6"]
instead of
[3,6,9]
My question is, where are these double quotes coming from?
for...in is a bad way of iterating array indices. Better use filter:
[1,2,3,4,5,6,7,8,9].filter(function(x) {
return x % 3 == 0;
}); // [3, 6, 9]
A for..in loop does not loop through the array elements, it loops through the indices of the array. So for:
var arr = ["a", "b", "c"]
for ( x in arr ) console.log( x );
You'll get the string keys of ["0", "1", "2"]
You can fix your code by replacing your loop with a native for loop:
for ( var x = 0; x < array.length; x++ ) {
if (array[i] % 3 == 0)
threes.push(array[i]);
}
So basically in x in array x is the index not the array value. Because anyway 0 is not in the array but your function is returning it as well. You should instead access the values using array[x]
There are various approaches, one of them is using .filter
function iLoveThree(array){
return array.filter(function(x){
return (x%3==0?1:0);
});
}
Or
function iLoveThree (array) {
var threes = [];
var x;
[].forEach.call(array, function(x){
if (x % 3 == 0) {
threes.push(x)
}
}
return threes
}
You're using a for..in loop which gives you the keys in an object, or in this case and array. Keys are always strings. Instead, you want to use a standard for loop.
for (var i = 0; i < array.length; i++) {
var x = array[i];
if (x % 3 === 0) {
threes.push(x);
}
}
Or if you want to use a more functional approach, you could use Array.prototype.filter.
return array.filter(function(x) {
return x % 3 === 0;
});
Not an answer to your question directly, but here's a nice way to pull every multiple of 3 from an array of numbers:
[1,2,3,4,5,6,7,8,9].filter(item => item % 3 === 0)
It seems that you are pushing in the indexes and not the actual values, go ahead and try the following:
function iLoveThree(array) {
var threes = [];
var x;
for (x in array) {
if (((x-2) % 3) == 0) {
threes.push(array[x])
}
}
return threes;
}
Another option, shorter, is:
function iLoveThree(arr) {
var threes = [];
for (var i = 2; i < arr.length; i = i + 3) {
threes.push(arr[i]);
};
return threes;
}
if you are comfortable with callback/predicate based loops, you could make stuff even shorter by filtering the array, instead of creating a new one:
function iLoveThree(arr) {
return arr.filter(function(x) {
return (x % 3) == 0;
});
}
Before you read the answer below, please read: Why is using “for…in” with array iteration such a bad idea? (Thanks to #Oriol for this link.)
Douglas Crockford has also discouraged the use of for..in. He recommends using array.forEach instead.
function iLoveThree (array) {
var threes = [];
array.forEach(function(item, i){ // use forEach, 'item' is the actual value and 'i' is the index
if (item % 3 === 0) {
threes.push(item); // you missed ; here
}
});
return threes; // you missed ; here
}
console.log(iLoveThree([1,2,3,4,5,6,7,8,9]));
Read up: Array.prototype.forEach() | MDN
If you read the for...in documentation, you will realize that you are pushing to threes the indexes (also called keys) not the values, because the variable x represents the index, so the value should be accessed by array[x].
function iLoveThree (array) {
var threes = [];
for (var x in array) {
if (array[x] % 3 == 0) {
threes.push(array[x])
}
}
return threes
}
There are several ways to achieve this, the best one is by using a filter, but that way was already explained by someone else, therefore I will use an exotic implementation using a reduce
[1, 2, 3, 4, 5, 6, 7, 8, 9].reduce(function(acc, e){return e % 3 == 0 ? acc.concat(e) : acc}, [])
Outputs 3, 6, 9
This question already has answers here:
Getting a random value from a JavaScript array
(28 answers)
Closed 7 years ago.
var items = Array(523, 3452, 334, 31, ..., 5346);
How do I get random item from items?
var item = items[Math.floor(Math.random()*items.length)];
1. solution: define Array prototype
Array.prototype.random = function () {
return this[Math.floor((Math.random()*this.length))];
}
that will work on inline arrays
[2,3,5].random()
and of course predefined arrays
var list = [2,3,5]
list.random()
2. solution: define custom function that accepts list and returns element
function get_random (list) {
return list[Math.floor((Math.random()*list.length))];
}
get_random([2,3,5])
Use underscore (or loDash :)):
var randomArray = [
'#cc0000','#00cc00', '#0000cc'
];
// use _.sample
var randomElement = _.sample(randomArray);
// manually use _.random
var randomElement = randomArray[_.random(randomArray.length-1)];
Or to shuffle an entire array:
// use underscore's shuffle function
var firstRandomElement = _.shuffle(randomArray)[0];
If you really must use jQuery to solve this problem (NB: you shouldn't):
(function($) {
$.rand = function(arg) {
if ($.isArray(arg)) {
return arg[$.rand(arg.length)];
} else if (typeof arg === "number") {
return Math.floor(Math.random() * arg);
} else {
return 4; // chosen by fair dice roll
}
};
})(jQuery);
var items = [523, 3452, 334, 31, ..., 5346];
var item = jQuery.rand(items);
This plugin will return a random element if given an array, or a value from [0 .. n) given a number, or given anything else, a guaranteed random value!
For extra fun, the array return is generated by calling the function recursively based on the array's length :)
Working demo at http://jsfiddle.net/2eyQX/
Here's yet another way:
function rand(items) {
// "~~" for a closest "int"
return items[~~(items.length * Math.random())];
}
Or as recommended below by #1248177:
function rand(items) {
// "|" for a kinda "int div"
return items[items.length * Math.random() | 0];
}
var random = items[Math.floor(Math.random()*items.length)]
jQuery is JavaScript! It's just a JavaScript framework. So to find a random item, just use plain old JavaScript, for example,
var randomItem = items[Math.floor(Math.random()*items.length)]
// 1. Random shuffle items
items.sort(function() {return 0.5 - Math.random()})
// 2. Get first item
var item = items[0]
Shorter:
var item = items.sort(function() {return 0.5 - Math.random()})[0];
Even shoter (by José dB.):
let item = items.sort(() => 0.5 - Math.random())[0];
var rndval=items[Math.floor(Math.random()*items.length)];
var items = Array(523,3452,334,31,...5346);
function rand(min, max) {
var offset = min;
var range = (max - min) + 1;
var randomNumber = Math.floor( Math.random() * range) + offset;
return randomNumber;
}
randomNumber = rand(0, items.length - 1);
randomItem = items[randomNumber];
credit:
Javascript Function: Random Number Generator
If you are using node.js, you can use unique-random-array. It simply picks something random from an array.
An alternate way would be to add a method to the Array prototype:
Array.prototype.random = function (length) {
return this[Math.floor((Math.random()*length))];
}
var teams = ['patriots', 'colts', 'jets', 'texans', 'ravens', 'broncos']
var chosen_team = teams.random(teams.length)
alert(chosen_team)
const ArrayRandomModule = {
// get random item from array
random: function (array) {
return array[Math.random() * array.length | 0];
},
// [mutate]: extract from given array a random item
pick: function (array, i) {
return array.splice(i >= 0 ? i : Math.random() * array.length | 0, 1)[0];
},
// [mutate]: shuffle the given array
shuffle: function (array) {
for (var i = array.length; i > 0; --i)
array.push(array.splice(Math.random() * i | 0, 1)[0]);
return array;
}
}
I've seen a few generators out there but they all make a squared matrix. For example, you give it a list of three items and it'll assume the output of the length is also three. However, I'd like to specify the items and the length.
Sound like an easy problem can't believe there isn't a library available for it. Would like to avoid writing this myself if there's a tested library out there. Any suggestions would be great.
Example of what i've found
var list = 'abc';
perms = permutations(list);
//you cannot define the length
Example
var list = 'abc';
var length = 3;
perms = permutations(list,length);
console.log(perms);
/* output
a,a,a
a,b,c
a,b,a
a,c,a
c,a,a
...
*/
I would like to be able to change length and should create permutations accordingly
length = 2
a,a
a,b
b,b
b,a
length = 4
a,a,a,a
a,a,a,b
....
You can imagine the length as representing the number of slots. Each slot has N possibilities, given that N is the number of elements in your initial list. So given three values [1,2,3], you will have a total of 3 x 3 x 3 = 27 permutations.
Here's my attempt. Comments included!
var list = [1,2,3];
var getPermutations = function(list, maxLen) {
// Copy initial values as arrays
var perm = list.map(function(val) {
return [val];
});
// Our permutation generator
var generate = function(perm, maxLen, currLen) {
// Reached desired length
if (currLen === maxLen) {
return perm;
}
// For each existing permutation
for (var i = 0, len = perm.length; i < len; i++) {
var currPerm = perm.shift();
// Create new permutation
for (var k = 0; k < list.length; k++) {
perm.push(currPerm.concat(list[k]));
}
}
// Recurse
return generate(perm, maxLen, currLen + 1);
};
// Start with size 1 because of initial values
return generate(perm, maxLen, 1);
};
var res = getPermutations(list, 3);
console.log(res);
console.log(res.length); // 27
fiddle
If you're looking for an answer based on performance, you can use the length of the array as a numerical base, and access the elements in the array based on this base, essentially replacing actual values from the base with the values in your array, and accessing each of the values in order, using a counter:
const getCombos = (arr, len) => {
const base = arr.length
const counter = Array(len).fill(base === 1 ? arr[0] : 0)
if (base === 1) return [counter]
const combos = []
const increment = i => {
if (counter[i] === base - 1) {
counter[i] = 0
increment(i - 1)
} else {
counter[i]++
}
}
for (let i = base ** len; i--;) {
const combo = []
for (let j = 0; j < counter.length; j++) {
combo.push(arr[counter[j]])
}
combos.push(combo)
increment(counter.length - 1)
}
return combos
}
const combos = getCombos([1, 2, 3], 3)
console.log(combos)
For smaller use cases, like the example above, performance shouldn't be an issue, but if you were to increase the size of the given array from 3 to 10, and the length from 3 to 5, you have already moved from 27 (33) combinations to 100,000 (105), you can see the performance difference here:
I wrote a little library that uses generators to give you permutations with custom items and number of elements. https://github.com/acarl005/generatorics
const G = require('generatorics')
for (let perm of G.permutation(['a', 'b', 'c'], 2)) {
console.log(perm);
}
// [ 'a', 'b' ]
// [ 'a', 'c' ]
// [ 'b', 'a' ]
// [ 'b', 'c' ]
// [ 'c', 'a' ]
// [ 'c', 'b' ]
I have a data dictionary like this:
var data = {
'text1': 1,
'text2': 2,
'text3': 3,
...
'text20': 20
];
I need to pick a random selection of those keys and then shuffle it's values. In the example, it should write something like this:
> console.log(choose(data, 5));
[ { key: 'text15', value: 8 },
{ key: 'text6', value: 3 },
{ key: 'text3', value: 15 },
{ key: 'text19', value: 6 },
{ key: 'text8', value: 19 } ]
For now I'm extracting the keys into another array and sorting by Math.random() but I'm stuck at swaping the values because no key should have the same value it initially had.
How would you swap key/values here?
Thanks
I put together a possible solution using underscore.js to simplify traversing the object and arrays in a cross browser manner:
var data = {
text1: 1,
text2: 2,
text3: 3,
text4: 4,
text5: 5,
text6: 6,
text7: 7,
text8: 8,
text9: 9,
text10: 10
};
function choose(data, num)
{
var keys = _.sortBy(
_.keys(data),
function(k)
{
return (Math.random() * 3) - 1;
}
),
results = [],
k1, k2;
if (num > keys.length) {
throw new Error('Impossible to retrieve more values than exist');
}
while (results.length < num) {
k1 = k2 || keys.pop();
k2 = keys.pop();
results.push({key:k1, value: data[k2]});
}
return results;
}
console.log(choose(data, 5));
This isn't necessarily an optimal approach but it seems to meet your requirements. I first grab all of the keys and sort them randomly. I then loop through the random keys creating a new object with one key and the following keys value. That way you'll always end up with a different value associated with each key. If you need it to work when the value of num passed in to the function == the number of keys in the data then you'll have to add a little more code - I'll leave that as an exercise for the reader :)
You can have a play with this code on jsfiddle:
http://jsfiddle.net/zVyQW/1/
You could do this:
collect names and corresponding values in two arrays names and values
shuffle both arrays independently of each other
take the first n items of both arrays and combine them
Here’s an example implementation:
Array.prototype.shuffle = function() {
for (var i=this.length-1, j, tmp; i>0; i--) {
j = Math.round(Math.random()*i);
tmp = this[i], this[i] = this[j], this[j] = tmp;
}
return this;
};
function choose(data, number) {
var names = [], values = [], pick = [];
for (var name in data) {
if (data.hasOwnProperty(name)) {
names.push(name);
values.push(data[name]);
}
}
names = names.shuffle(), values = values.shuffle();
for (var i=Math.min(number >>> 0, names.length-1); i>=0; i--) {
pick.push({key: names[i], value: values[i]});
}
return pick;
}
Been a while since this was answered, but I was working on shuffling and found the following to be by far the fastest implementation with an evenly random distribution.
It's fast because it only makes one call to Math.random on each iteration, all the rest is done by property access. It doesn't modify the array, just reassigns values.
function shuffle(a) {
var t, j, i=a.length, rand=Math.random;
// For each element in the array, swap it with a random
// element (which might be itself)
while (i--) {
k = rand()*(i+1)|0;
t = a[k];
a[k]=a[i];
a[i]=t;
}
return a;
}
It uses a combination of three functions (including the Array shuffle prototype method).
Here is the complete code:
var obj = {
"red":"RED",
"blue":"BLUE",
"green":"GREEN",
"yellow":"YELLOW",
"purple":"PURPLE"
};
Array.prototype.shuffle = function(){
for (var i = 0; i < this.length; i++){
var a = this[i];
var b = Math.floor(Math.random() * this.length);
this[i] = this[b];
this[b] = a;
}
}
obj = shuffleProperties(obj); // run shuffle
function shuffleProperties(obj) {
var new_obj = {};
var keys = getKeys(obj);
keys.shuffle();
for (var key in keys){
if (key == "shuffle") continue; // skip our prototype method
new_obj[keys[key]] = obj[keys[key]];
}
return new_obj;
}
function getKeys(obj){
var arr = new Array();
for (var key in obj)
arr.push(key);
return arr;
}
for(key in obj){
alert(key);
}
Check all post,
Best Regards.
Use an implementation of random that randomizes a discrete set of values, such as Math.rand seen here. For each index, randomize Math.rand(index, length-1) to get a list of random indexes, the location off all indices will change.