Please help! I need to declare an empty array (foodTray = []), and run a loop 5x (for each iteration push a food type), the foodTray has to hold a max of 2 types but the total length should not exceed 5.
const foodTypes = ['seafood', 'nuts', 'seeds'];
I had done this =>
'use strict';
let foodTray = [];
const foodTypes = ['seafood', 'nuts', 'seeds'];
for (let x = 0; x < foodTypes.length; x++) {
const food = foodTypes[x];
foodTray.push(food);
if (foodTray.length < 5) {
foodTray.push(food);
}
}
console.log('I have ' + `${foodTray}.`);
but I was instructed the loop had to run 5 times***** and what I used was the length of the foodTypes.
The desired output should be => I have seafood, seafood, nuts, nuts, seeds.
The problem: I did for (let x = 0; x < *foodTypes.length*; x++)
instead, the loop should run 5 times! I am not sure how I can iterate twice over an element.
Your original code is giving you the desired output which is : I have seafood, seafood, nuts, nuts, seeds.
let foodTray = [];
const foodTypes = ['seafood', 'nuts', 'seeds'];
for (let x = 0; x < foodTypes.length; x++) {
const food = foodTypes[x];
foodTray.push(food);
if (foodTray.length < 5) {
foodTray.push(food);
}
}
console.log('I have ' + `${foodTray}.`);
Related
In a dataset I have different locators. Some places are free (locator = null). I would like to capture these and push them into arrays.
In the subarray may only be locations that are in a row. If a distance is greater than 1 then it comes to the next array.
const freeLocs = locs.filter(elem => !elem.locator)
let temp = []
let array2D = []
for(let i = 0; i < freeLocs.length-1; i++) {
let abs = Math.abs(freeLocs[i+1].position - freeLocs[i].position)
temp.push(freeLocs[i])
if(abs > 1) {
array2D.push(temp)
temp = []
}
}
console.log(array2D)
Now I have the problem that the last array is not filled.
https://jsfiddle.net/5yk0mpt9/2/
Problem starts here:
for(let i = 0; i < freeLocs.length-1; i++) {
with this condition you lose the last item of the array:
i < freeLocs.length-1
it needs to change like this:
i < freeLocs.length
but it also needs an extra check inside the loop before trying to get the
freeLocs[i + 1].position
for the last iteration
for example:
for (let i = 0; i < freeLocs.length; i++) {
temp.push(freeLocs[i]);
if (
(i === freeLocs.length - 1) ||
(Math.abs(freeLocs[i + 1].position - freeLocs[i].position) > 1)
) {
array2D.push(temp)
temp = [];
}
}
working demo here: DEMO
I possibly am looking at this incorrectly, but I'm trying to make a tournament bracket creator. You input names that are entered into an Object called players I only want each side of the bracket to have four players in it. So I thought the best course of action would be to find out how many sides i would have in the bracket, once I had that I could look over those sides and for each loop I could place players in those sides but I've run into a bit of a problem. I'm not sure how to dynamically create these sides each pass. I removed some of my bad code so you can see kind of the idea I have
const players = []
function Player(name, deck){
this.name = name
this.deck = deck
this.points = 0
this.id = players.length + 1
}
function addPlayer(){
let player = new Player (
document.getElementById('name').value,
document.getElementById('deck').value
)
//console.log(player)
document.getElementById('name').value = ''
document.getElementById('deck').value = ''
players.push(player)
logPlayers()
}
function logPlayers (){
output = ''
for (let index = 0; index < players.length; index++) {
output += (index + 1) + ') ' + players[index].name + ' | ' + players[index].deck + '<br>'
}
document.getElementById('output').innerHTML = output
}
function initGame(){
game = ''
let cube = []
const four = Math.floor(players.length/4)
//console.log(four)
const remainder = four % 1
for (let index = 0; index < four; index++) {
for (let j = 0; j < 4; j++) {
}
}
}
My array cube is what I was gonna uses as my sides and four is how many of those sides I will have. I will loop over them, and inside that loop I'll ensure I only put 4 players into each, however I'm getting confused on how I will create different cubes each pass.
I hope I explained this correctly
let cube = []
const four = Math.ceil(players.length/4)
let playerIndex = 0;
for (let index = 0; index < four; index++) {
for (let j = 0; j < 4; j++) {
if (!cube[index]) {
cube[index] = [];
}
cube[index].push(player[playerIndex])
playerIndex++
}
}
This could be what you want?
player[playerIndex] will be the individual player by their array index, assuming player is an array containing the players.
I have a very basic implementation of k-means in javascript (I know but it needs to run in the browser). What I would like to understand is - how could one make this more functional?
It is currently full of loops, and extremely difficult to follow / reason about, code below:
export default class KMeans {
constructor(vectors, k) {
this.vectors = vectors;
this.numOfVectors = vectors.length;
this.k = k || bestGuessK(this.numOfVectors);
this.centroids = randomCentroids(this.vectors, this.k);
}
classify(vector, distance) {
let min = Infinity;
let index = 0;
for (let i = 0; i < this.centroids.length; i++) {
const dist = distance(vector, this.centroids[i]);
if (dist < min) {
min = dist;
index = i;
}
}
return index;
}
cluster() {
const assigment = new Array(this.numOfVectors);
const clusters = new Array(this.k);
let movement = true;
while (movement) {
// update vector to centroid assignments
for (let i = 0; i < this.numOfVectors; i++) {
assigment[i] = this.classify(this.vectors[i], euclidean);
}
// update location of each centroid
movement = false;
for (let j = 0; j < this.k; j++) {
const assigned = [];
for (let i = 0; i < assigment.length; i++) {
if (assigment[i] === j) assigned.push(this.vectors[i]);
}
if (!assigned.length) continue;
const centroid = this.centroids[j];
const newCentroid = new Array(centroid.length);
for (let g = 0; g < centroid.length; g++) {
let sum = 0;
for (let i = 0; i < assigned.length; i++) {
sum += assigned[i][g];
}
newCentroid[g] = sum / assigned.length;
if (newCentroid[g] !== centroid[g]) {
movement = true;
}
}
this.centroids[j] = newCentroid;
clusters[j] = assigned;
}
}
return clusters;
}
}
It certainly can.
You could start with this:
classify(vector, distance) {
let min = Infinity;
let index = 0;
for (let i = 0; i < this.centroids.length; i++) {
const dist = distance(vector, this.centroids[i]);
if (dist < min) {
min = dist;
index = i;
}
}
return index;
}
Why is this a member function? Wouldn't a pure function const classify = (centroids, vector, distance) => {...} be cleaner?
Then for an implementation, let's change the distance signature a bit. If we curry it to const distance = (vector) => (centroid) => {...}, we can then write
const classify = (centroids, vector, distance) =>
minIndex (centroids .map (distance (vector)))
And if that distance API is out of our control, it's not much harder:
const classify = (centroids, vector, distance) =>
minIndex (centroids .map (centroid => distance (vector, centroid)))
Granted, we haven't written minIndex yet, but we've already broken the problem down to use a more meaningful abstraction. And minIndex isn't hard to write. You can do it imperatively as the original classify function did, or with something like this:
const minIndex = (xs) => xs.indexOf (Math.min (...xs))
Note that distance is a slightly misleading name here. I had to read it more carefully because I assumed a name like that would represent..., well a distance. Instead it's a function used to calculate distance. Perhaps the name metric or something like distanceFunction, distanceFn, or distanceImpl would be more obvious.
Now let's move on to this bit:
const newCentroid = new Array(centroid.length);
for (let g = 0; g < centroid.length; g++) {
let sum = 0;
for (let i = 0; i < assigned.length; i++) {
sum += assigned[i][g];
}
newCentroid[g] = sum / assigned.length;
if (newCentroid[g] !== centroid[g]) {
movement = true;
}
}
This code has two responsibilities: creating the newCentroid array, and updating the value of movement if any value has changed.
Let's separate those two.
First, creating the new centroid. We can clean up that nested for-loop to something like this:
const makeNewCentroid = (centroid, assigned) =>
centroid .map ((c, g) => mean (assigned .map ((a) => a[g])))
This depends on a mean function, which we'll write along with its required sum function like this:
const sum = (ns) => ns .reduce ((t, n) => t + n, 0)
const mean = xs => sum (xs) / xs.length
Then we need to update movement. We can do that easily based on centroids and newCentroids:
movement = centroids.some((c, i) => c !== newCentroids[i])
Obviously, you can continue in this manner. Each for loop should have a fundamental purpose. Find that purpose and see if one of the Array.prototype methods could better express it. For the second section we worked with above, we found two purposes, and just split them into two separate blocks.
This should give you a good start on making this more functional. There is no magic bullet. But if you think in terms of pure functions on immutable data, and on strong separation of concerns, you can usually move in a functional direction.
How can I run a loop 20 times for an array that have only two entries?
I have the following code
const genders = ['male', 'female'];
const randChoice = arr => {
return arr[Math.floor(Math.random() * arr.length)];
};
const loop = () =>
for (let i = ''; i <= 20; i++) {
const data = randChoice(genders);
if(data === 'male') {
const name = randChoice(maleNames);
people.push(new Data(data, name, lastName))
} else {
const name = randChoice(femaleNames);
people.push(new Data(data, name, lastName))
}
console.log('people', people)
return people;
I have tried some different things but never get it working and looping 20 times.
thanksa for all answers.
But let make this more complex
in thisd case. This will not work
The mistake is at Line 8, when you wrote for (let i = ''; i <= 20; i++), you need to first set the variable i to 0, like this: for (let i = 0; i <= 20; i++).
The whole code for your loop will then be:
for (let i = 0; i < 20; i++) {
const data = randChoice(genders);
// here goes if else statement for gender
}
Another mistake that also #Hasan Balcı has pointed out, is that in your code, the loop runs 21 times instead of 20. Why? Because the variable i starts from 0, and the loop runs until it reaches 20, including when its value is 20!
To correct this, instead of writing for (let i = 0; i <= 20; i++), it will have to be for (let i = 0; i < 20; i++), changing i <= 20 to i < 20!
Hope this helped!
Like this you can iterate loop for 20 times:
const loop = () =>{
for (let i = 0; i < 20; i++) {
const data = randChoice(genders);
console.log(data);
}}
Can you please write a js code that fills empty matrix randomly with 0 or 1? I need to use Random() function.
I wrote this code and I got an error Random() is not defined
var matrix = [];
for(var y = 0; y<5; y++){
for(var x = 0; x<5; x++){
let arr = [0,1]
matrix[y][x]= random(arr)
matrix.push(matrix[y][x])
}
}
You should Math.random() and then use Math.round() to get 0 or 1.
Secondly you should set matrix[y] to an empty array otherwise code will throw error.
var matrix = [];
for(var y = 0; y<5; y++){
matrix[y] = [];
for(var x = 0; x<5; x++){
matrix[y][x]= Math.round(Math.random())
matrix.push(matrix[y][x])
}
}
console.log(matrix)
An easier to create a matrix of any length you can use map(). Create an array of given length and map it to a another array with same length have random values from 0 or 1
const getMatrix = len => [...Array(len)].map(x => [...Array(len)].map(b => Math.round(Math.random())));
let res = getMatrix(5);
console.log(res)
For different length and width use two parameters.
const getMatrix = (l,w) => [...Array(l)].map(x => [...Array(w)].map(b => Math.round(Math.random())));
let res = getMatrix(2,3);
console.log(res)
You should use Math.round(Math.random()).
An easy way to do it using ES6:
const arr = new Array(5).fill().map(() => new Array(5).fill().map(() => Math.round(Math.random())));
console.log(arr);
You have to use the fill() method before map(), otherwise you will get undefined values.
The "classical" way to do it using your snippet of code will be similar to what you tried, with the addition of the standard built-in object Math which has the random() method and also round() to get integer values. If you want a matrix (2D array) then you will need to push an array into each row, otherwise you will get a simple array.
var matrix = [];
for(var y = 0; y < 5; y++) {
const row = [];
for(var x = 0; x < 5; x++) {
row.push(Math.round(Math.random()));
}
matrix.push(row);
}
console.log(matrix);