Javascript get random variables from array but each just once - javascript

I´d like to get random variables from a javascript and prepend it to a div container like that:
// my Array
var thumbnailArray = new Array();
thumbnailArray[0] = 'contentarray1';
thumbnailArray[1] = 'contentarray2';
thumbnailArray[2] = 'contentarray3';
function thumbnailquery () {
for (var i = 0; i <= 3; i++) {
$('#myDiv').prepend(thumbnailArray[Math.floor(Math.random() * thumbnailArray.length)])
}
}
Now how can i ensure that each variable is only taken once but still randomly?
Thank You

Shuffle the array and pop of values instead
function shuffle(a) {
var c=a.length,t,r;
while (0 !== c) {
r = Math.floor(Math.random() * c);
c -= 1;t = a[c];a[c] = a[r];a[r] = t;
}
return a;
}
var thumbnailArray = [
'contentarray1',
'contentarray2',
'contentarray3'
];
shuffle( thumbnailArray );
thumbnailquery();
function thumbnailquery () {
for (var i = 0; i <= 3; i++) {
$('#myDiv').prepend( thumbnailArray.pop() );
}
}
FIDDLE

Copy the array. Then delete objects that you took from the copied array.

There's no elegant way to do it the way you describe. You could construct an array of "selected indices" and ensure that each random number didn't already exist in that array, but that has a worst case operating time of infinity so highly not recommended.
Your best bet would be to shuffle the array and then iterate over, selecting the elements in order (shuffled order).
See this Stack Overflow for a good way to shuffle an array in JavaScript
How can i shuffle an array in JavaScript?

Use splice() http://www.w3schools.com/jsref/jsref_splice.asp
randNum = thumbnailArray[Math.floor(Math.random() * thumbnailArray.length)]
$('#myDiv').prepend(splice(randNum,1))

Related

Creating new array from unique elements found in array

I was given an assignment:
Finding unique elements in an array and creating a new array from these unique elements.
The professor gave us the pseudocode to code this assignment - it should be straightforward but my code is not working.
Here is my attempt:
// search for unique birthdays in the array
function find(birthdays) {
var uniqueBirthdays = [];
for (var i = 1; i <= birthdays.length; i = i + 2) {
var count = 0;
for (var j = 1; j <= birthdays.length; j = j + 2) {
if (birthdays[i] == birthdays[j]) {
count++;
}
}
if (count == 1) {
var n = uniqueBirthdays.length;
uniqueBirthdays[n] = birthdays[i - 1];
}
}
return uniqueBirthdays;
}
I have tried checking for indentation errors as well as a number of other things but can not figure out why as the array is traversed it is giving each element a count of only 1 (meaning there are no matching elements) - it does not seem to be traversing the array more than once so no elements have a count greater than 1 - even though I am using nested for loops.
I have increased the intervals by 2 because I need to compare every other element - there is a number assigned to each birthday so the array may look like:
['0001'][12/15]['0002'[03/12]...
I am brand new so I may be overlooking simple but ive tried so many things and i can not understand why this code isnt working - it is returning back all of the elements that are assigned to the birthdays instead of just the unique ones.
Any help that will point me in the right direction is very much appreciated.
You were very close, and there were just a couple mistakes. The only things that did not work were the way you wrote your for loops:
for (var i = 1; i <= birthdays.length; i = i + 2) {
Array indexes start at 0, so if you want to process the first element, use var i = 0;
Since these indexes start at 0, for an Array of 3 elements, the last index is 2. So you only want to run your loop while i is less than the array length: i < birthdays.length
You were skipping elements by doing i = i + 2. There seems to be no reason for it?
Something else worth mentionning: in JS, indentation does not matter - well, it does, but only to avoid making your eyes bleed. In fact, most websites use minified versions of their code, which fits on a single (often very long and ugly) line (example).
Here is your code, with only two lines fixed:
function find(birthdays) {
var uniqueBirthdays = [];
for (var i = 0; i < birthdays.length; i = i + 1) { // <-----
var count = 0;
for (var j = 0; j < birthdays.length; j = j + 1) { // <-----
if (birthdays[i] == birthdays[j]) {
count++;
}
}
if (count == 1) {
var n = uniqueBirthdays.length;
uniqueBirthdays[n] = birthdays[i];
}
}
return uniqueBirthdays;
}
// I used letters instead of birthdays for easier demo checking
var birthdays = ['a', 'b', 'a', 'c'];
console.log( find(birthdays) ); // ["b", "c"]
JS have direct methods tor that use Array.indexOf(), Array.lastIndexOf() and Array.filter()
uniques elements have same first position and last position
sample code:
const initailArray = [...'ldfkjlqklnmbnmykdshgmkudqjshmjfhmsdjhmjh']
const uniqueLetters = initailArray.filter((c,i,a)=>a.indexOf(c)===a.lastIndexOf(c)).sort()
console.log(JSON.stringify(uniqueLetters))

How do I loop over an array at a given key on an object?

I was given the assignment to create a function that, given an object and a key, returns an array containing all the elements of the array located at the given key that are less than 100. I came up with this:
function getElementsLessThan100AtProperty(obj, key) {
var lessThan100 = [];
var targetedKey = obj[key];
if (targetedKey === undefined) {
return [];
}
for (i = 0; i < targetedKey.length; i++) {
if (targetedKey[i] < 100) {
lessThan100.push(targetedKey[i]);
}
}
return lessThan100;
}
Now this works, but I am wondering why my original code didn't. I tried to loop over the array at the given property by writing the code below, but it didn't work. Why can't i do this? Also, would someone show me how to clean up this code to make it shorter?
for (i = 0; i <obj[key].length; i++) {
if (obj[key[i]].length < 100) {
lessThan100.push(obj[key[i]]);
}
Because obj[key[i]] has to be obj[key][i], additionally you check if the length is smaller 100 which is probably not your intention.
The whole code could be written as:
const getLessThanHundred = (obj, key) =>
obj[key].filter(it => it < 100);
In your revised code you are checking if the length of the item in the array is less than 100, not if the value of the item is less than 100. You should be checking the value (ie < 100; not .length < 100)

Manipulate more javascript array based on another array

I've a strange thing to do but I don't know how to start
I start with this vars
var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];
So to start all the 3 array have the same length and the very first operation is to see if there is a duplicate value in sky array, in this case the 0 is duplicated and only in this case is at the end, but all of time the sky array is sorted. So I've to remove all the duplicate (in this case 0) from sky and remove the corresponding items from base and sum the corresponding items on ite. So if there's duplicate on position 4,5 I've to manipulate this conditions. But let see the new 3 array:
var new_base = [1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var new_sky = [0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var new_ite = [139,38,13,15,6,4,6,3,2,1,2,1,1,1];
If you see the new_ite have 139 instead the 64,52,23, that is the sum of 64+52+23, because the first 3 items on sky are the same (0) so I remove two corresponding value from base and sky too and I sum the corresponding value into the new_ite array.
There's a fast way to do that? I thought a for loops but I stuck at the very first for (i = 0; i < sky.length; i++) lol, cuz I've no idea on how to manipulate those 3 array in that way
J
When removing elements from an array during a loop, the trick is to start at the end and move to the front. It makes many things easier.
for( var i = sky.length-1; i>=0; i--) {
if (sky[i] == prev) {
// Remove previous index from base, sky
// See http://stackoverflow.com/questions/5767325/how-to-remove-a-particular-element-from-an-array-in-javascript
base.splice(i+1, 1);
sky.splice(i+1, 1);
// Do sum, then remove
ite[i] += ite[i+1];
ite.splice(i+1, 1);
}
prev = sky[i];
}
I won't speak to whether this is the "fastest", but it does work, and it's "fast" in terms of requiring little programmer time to write and understand. (Which is often the most important kind of fast.)
I would suggest this solution where j is used as index for the new arrays, and i for the original arrays:
var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];
var new_base = [], new_sky = [], new_ite = [];
var j = -1;
sky.forEach(function (sk, i) {
if (!i || sk !== sky[i-1]) {
new_ite[++j] = 0;
new_base[j] = base[i];
new_sky[j] = sk;
}
new_ite[j] += ite[i];
});
console.log('new_base = ' + new_base);
console.log('new_sky = ' + new_sky);
console.log('new_ite = ' + new_ite);
You can use Array#reduce to create new arrays from the originals according to the rules:
var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330];
var sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17];
var ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1];
var result = sky.reduce(function(r, n, i) {
var last = r.sky.length - 1;
if(n === r.sky[last]) {
r.ite[last] += ite[i];
} else {
r.base.push(base[i]);
r.sky.push(n);
r.ite.push(ite[i]);
}
return r;
}, { base: [], sky: [], ite: [] });
console.log('new base:', result.base.join(','));
console.log('new sky:', result.sky.join(','));
console.log('new ite:', result.ite.join(','));
atltag's answer is fastest. Please see:
https://repl.it/FBpo/5
Just with a single .reduce() in O(n) time you can do as follows; (I have used array destructuring at the assignment part. One might choose to use three .push()s though)
var base = [1,1,1,2,3,5,7,9,14,19,28,40,56,114,232,330],
sky = [0,0,0,3,4,5,6,7,8,9,10,11,12,14,16,17],
ite = [64,52,23,38,13,15,6,4,6,3,2,1,2,1,1,1],
results = sky.reduce((r,c,i) => c === r[1][r[1].length-1] ? (r[2][r[2].length-1] += ite[i],r)
: ([r[0][r[0].length],r[1][r[1].length],r[2][r[2].length]] = [base[i],c,ite[i]],r),[[],[],[]]);
console.log(JSON.stringify(results));

How can i push a array in another array?

i have a main array with 64 positions, for each position i need another array. like: someArray[index] = [someObject].
How can i create those arrays ? and How can i get someObject.name , someObject.lastName ?
Here is the code:
$scope.filaCores = [];
$scope.object = {}
$scope.object.name = "name";
$scope.object.secondname= "secondname";
for(var i = 0; i <10; i++) {
$scope.filaCores[i] = [$scope.object.name, $scope.object.secondname];
}
Here you go: https://jsfiddle.net/jsg81gg8/1/
Based on your description I do not see the need for an array of arrays. But since that is what you asked for here you go. You didn't specify how many array elements for the sub array so I'm going to show an example with three. If you only need 64 total structures then the inner array is not needed.
window.getRandomInt = function() {
return Math.floor(Math.random() * (10000 - 1 + 1)) + 1;
}
mainArray = []; /* you said you wanted 64 of these */
subArray = []; /* you didn't specify how many of these, the example below will assume 3 per each mainarray */
for (i = 0; i < 64; i++) {
for (j = 0; j < 3; j++) {
/* I'm using getRandomInt() just so you can see all the names are different */
subArray[j] = {name:"John"+getRandomInt(), lastname:"Doe"+getRandomInt()};
}
mainArray[i] = subArray;
}
/* Press F12 and go to the console tab, run this script, and you will see the output of the entire array */
console.log(mainArray);
/* You can access a specific element like this... */
alert('Alerting mainArray[23][2].lastname: '+mainArray[23][2].lastname);
If you really don't need the sub array, and you only need 64 structures then it could be simplified to look like this: https://jsfiddle.net/Ldafbwbk/1/
UPDATE: And here is a third example that more closely resembles your updated question: https://jsfiddle.net/7st8fnw5/3/

Find maximum variable using JavaScript

I have thirty variables which are all numbers:
h0 = 23
h1 = 27
h2 = 90
...
How do I find the largest variable?
The output here should be h2.
Assuming the variables are all named in consecutive order, you can add them to an array:
var values = [h0, h1, ....h29];
Then iterate over the array, compare the values and keep track of the index of the max value:
var maxIndex = 0;
for (var i = 1; i < values.length; i++) {
if (values[maxIndex] < values[i]) {
maxIndex = i;
}
}
maxIndex will now contain the index of the maximum value, and you could concat it with 'h', e.g.
console.log('h' + maxIndex);
Of course this approach makes a lot of assumptions and is fragile, but that's what you get when doing this kind of "meta-programming" (the variable name really should not be of any concern to anybody using the app).
Using an object would make it a bit better, at least concerning the variable name:
var values = {
h0: h0,
h1: h1,
...
};
var maxProp = '';
for (var prop in values) {
if (values[maxProp] < values[prop]) {
maxProp = prop;
}
}
Put them in an array instead of individual variables, then loop over the array.
To brute-force it, compare adjacent pairs of variables, then pairs of the results, until only one is left.
If you want the answer to be 'h2' instead of '90' (per comment), try using an Object instead of separate variables (or an array, as mentioned in other answers).
var find_max = {
'h0': 23,
'h1': 27,
'h2': 90,
// and so on
};
Then loop over the properties of the object to find the maximum.
var max;
for (var h in find_max) {
if (!max || (find_max[h] > find_max[max])) {
max = h;
}
}
You can probably improve this loop - try using hasOwnProperty to make sure that the only items in the loop are the ones you want.
You can get it easily by checking the window object using the bracket notation this way:
h0 = 11;
h1 = 24;
h2 = 28;
h3 = 345;
h4 = 1;
var i = 0;
var max = {
name: 'none',
val: 0
};
while (nextItem = window['h'+i]) {
if (nextItem > max.val) {
max = {
name: 'h'+i,
val: nextItem
};
};
i++;
};
document.getElementById('max').innerHTML = max.name + ' = ' + max.val;
<p>Maximum is: <span id="max"></span></p>
EDIT: I was too hasty in posting the below as it didn't take into account the real question. Since then there have been good answers presented so I'll just show a way that you can sort the variables in descending order. One way would be to place the numbers in an array of objects such that:
numArray = [{name:h0, value:23}, {name:h1, value:27}, {name:h2, value:90}];
And do:
numArray.sort(function(a, b){
return b.value - a.value;
});
According to this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
It looks pretty easy once you have the numbers in an array. You could call
Math.max.apply(null, numArray)
on the array, or, using ES6, you could say Math.max(...numArray) (... is the "spread" operator).
You could also do a sort:
numArray.sort(function(a, b){
return b - a;
});
Which would sort your array in descending order with the maximum number now at numArray[0].

Categories

Resources