JavaScript default constructor| array | loops - javascript

I need to make a script but I have no idea how to complete it.
This is what I have to do:
(1) Write a class Boxes. this class has a default constructor and an empty array named boxes.
further has this class 3 methods:
1) insert add method to put Box into the boxes-array.
2) insert method size to get the actual size of the array.
3) insert toString method which give color and volume back in one string.
(2) continue in the init function:
2.3 turn a loop around every object from the array objects to add it to the array boxes
2.4 make a toString method to give back every object from your array in one HTML P-tag.
I hope this makes sense to you guys and it would be a big help if somebody could help me!
A big thanks in advance!
Update: I have edited the code to what I have now.
window.addEventListener("load", init, false);
function init() {
// (2.1)
let object1 = new Box(20, 8, 3, "white");
let object2 = new Box(30, 20, 10, "Brown");
let object3 = new Box(50, 40, 20);
// (2.2)
let boxes = new Boxes();
// (2.3)
boxes.push(object1);
boxes.push(object2);
boxes.push(object3);
// 2.4
var str=""
for (let i = 0 ; i < boxes.size() ; i++){
str += "<p>"+boxes.toString(i)+"<p>"
}
}
class Box {
constructor(length, width, height, color = "blue") {
this.length = length;
this.width = width;
this.heigt = height;
this.color = color;
}
volume() {
return this.length * this.width * this.height;
}
toString() { // String templates
return `Volume: ${this.volume()} --- Kleur: ${this.color}`;
}
}
// (1) class Boxes
class Boxes {
constructor(){
this.boxes = [];
}
add(Box){
this.boxes.push(Box);
}
size(){
return this.boxes.length;
}
toString(i){
this.boxes[i].toString();
}
}

I don't quite get what's 3) means so I would assume that you want to get the box color and volume given the index (correct me if I'm wrong)
class Boxes{
//init property called boxes to an empty array when creating Boxes object
constructor(){
this.boxes = [];
}
//return the length of the boxes
size(){
return this.boxes.length;
}
//add a box by pushing it to the array
add(box){
this.boxes.push(box);
}
//print the volume and color of a box given the index
toString(i){
this.boxes[i].toString();
}
}
for number 2:
//2.3
//do you have to push the objects to object?
//use this if you don't have to
boxes.push(object1);
boxes.push(object2);
boxes.push(object3);
//use this if you pushed your objects into an array called object
objects.forEach(function(singleObject){
boxes.push(singleObject);
});
//2.4
//Iterate every object in boxes and print out their volume and color
//Do you have to create a P tag or just wrapped the string with <p></p>?
//This answer assumes that you just wrap it with <p></p>. Correct me if I'm wrong
var str = "";
//option 1 Using foreach loop
boxes.boxes.forEach((singleBox){
str += "<p>"+singleBox.toString()+"</p>";
});
//option 2 Using for loop
for(var i = 0; i < boxes.size(); i++){
str += "<p>"+boxes.toString(i)+"</p>";
}
//now str contains every object's color and volume wrapped in P tag
I would recommend you to go through this course https://www.codecademy.com/learn/javascript

Related

How to access variables and methods of objects within an array [resolved]

So I have a class that looks something like this:
class Car {
constructor(name, pos) {
this.carName = name;
this.carPos = pos;
}
}
I then end up creating an array of objects using this class as so:
newCar = new Car("Fusion","100 100");
let carManifest = [newCar]
I later in my code go on to carManifest.push() several other Car objects into the array, building it up. Eventually I run into a for loop such that:
for (index = 0; index < carManifest.length; index++) {
if(carManifest[index].carName === 'Honda')
<Do Stuff>
}
Whenever I go to access carManifest[index].carName I get "undefined". I also had a get method within the object for the same variable, but using that in this context wouldn't even compile. I am aware that the array itself does not have these variables, but as far as I'm aware there is no way to declare an array to be of a specific class in JS like you can in Java and C.
Could anyone help me out? I am new to JS and have been stumped on this for the past hour. I will be glad to update this if there is not enough info. Thanks!
Note: Not sure if it matters but I am using Node.js
Change your code from
let carManifest = [newCar]
to push item to array as
carManifest.push(newCar);
/*
function Car (name, pos) {
this.carName = name;
this.carPos = pos;
}
*/
class Car {
constructor(name, pos) {
this.carName = name;
this.carPos = pos;
}
}
newCar = new Car("Fusion","100 100");
let carManifest = [];
carManifest.push(newCar);
for (index = 0; index < carManifest.length; index++) {
if(carManifest[index].carName === 'Fusion'){
console.log(carManifest[index].carName);
}
}
Are you pushing other variables or objects into the same array? There is nothing wrong with the code examples you're showing, you are able to access the variables of the objects this way. You'll have to show more code, where exactly are you getting undefined?

Why do both of these variables change when only one is supposed to?

The following is a subroutine that I excised from my main program. It executes as a stand-alone script, but does not behave in the intended manner any better than it did in the main program:
//Generate permanent array of all possible directional marker pairs,
//excluding 0,0. Also generate array length the "hard" way
var potential_direction_pairs = [];
var length_of_potential_direction_pairs_array = 0;
for (var x_count = -1; x_count < 2; x_count++) {
for (var y_count= -1; y_count < 2; y_count++) {
if (x_count == 0 && y_count == 0) {}
else {
potential_direction_pairs.splice(0, 0, [x_count, y_count]);
length_of_potential_direction_pairs_array += 1
}
}
}
//Create temporary and mutable copy of permanent directional marker array.
var direction_pairs_being_tried = potential_direction_pairs;
//Iterate over all elements in temporary marker array. Use permanent array
//length, as temporary array length will change with each loop.
for (var count = 0, current_direction_pair_being_tried; count < length_of_potential_direction_pairs_array; count++) {
//Count out current length of (shrinking) temporary array.
for (var pair_index = 0; direction_pairs_being_tried[pair_index] != undefined; pair_index++) {}
//Choose a random marker pair from temporary array...
var random_index = Math.floor(Math.random() * pair_index);
//...and store it temporarily in a single-pair array.
current_direction_pair_being_tried = direction_pairs_being_tried[random_index];
//Remove the randomly chosen marker pair from larger temporary array.
direction_pairs_being_tried.splice(random_index, 1);
//Insert temporary "tracer" to display current state of intended
//"permanent" array.
console.log("Potential direction pairs: " + potential_direction_pairs);
//Insert another "tracer" to display current state of intended
//temporary array.
console.log("Direction pairs being tried: " + direction_pairs_being_tried);
//"Tracer" showing current state of temporary single-pair array.
console.log("Current direction pair being tried: " + current_direction_pair_being_tried);
}
Only one of the two "2D" arrays is meant to change, but as you can see from the following screenshot of terminal window output, both do: output of simple subroutine. My knowledge of scope/closure/etc is still pretty shaky, but my suspicions lie that direction. Any help would be appreciated (including a brief explanation), but I'm especially keen on the simplest possible correction to make this work.
Thanks in advance,
Rob
var direction_pairs_being_tried = potential_direction_pairs; is not a copy of an array, it's pointing to the same array. You can copy an array with
var direction_pairs_being_tried = potential_direction_pairs.slice()

Show a specific number of random objects from a selection and hide all others with js/jQuery?

What I did so far was the following:
function randomSelectObjects(randObjects, countShow){
var i = 0;
var countRandObjects = randObjects.length;
var preselectedObj = false;
randObjects.hide(); // hide all items
while (i < countShow) { // while until we found enough items we can show
preselectedObj = randObjects.eq(Math.floor(Math.random()*countRandObjects)); // random select an object
if(preselectedObj.is(':hidden')){ // make sure it is not already unhidden
preselectedObj.show(); // show the object
i++; // up the counter – done only in case it was not already visible
}
}
}
Usage:
var randObjects = $('.items');
randomSelectObjects(randObjects, 1);
The problem is that I will run into selecting an already revealed (show()) item inside while from time to time. I would love to remove that unnecessary overhead.
Unfortunately there seems to be no way to remove an object from a cached selection. remove() also removes the object from the DOM which is not (always) what I want.
Cloning the selection of objects first and then using remove() would work for the selection process but then there would be the overhead to match the selected items with the live DOM for actually show() them.
My suggestion is create a unique random array first. Hide all elements then loop through the array of random inidices and show matching elements
// wrap in simple jQuery plugin
$.fn.randomDisplay = function(max_items) {
max_items = max_items || 5;
//create array of unique random indices
var randArr = randArray(this.length, max_items);
// hide all then filter matches to show
this.hide().filter(function(i){
return randArr.indexOf(i) >-1
}).show();
// creates unique array
function randArray(max, len) {
var arr = [], rand;
for (var i = 0; i < len; i++) {
rand = getRand(max)
while (arr.indexOf(rand) > -1) {
rand = getRand(max)
}
arr.push(rand);
}
return arr;
}
// random number helper
function getRand(max) {
return Math.floor(Math.random() * max)
}
}
// use
$(function(){
$('.item').randomDisplay(7)
})
DEMO

Issue with for loop and if statements in javascript

I am using Javascript and Openlayers library in order to style a vector feature on the map.
I have written the following script:
var gidS = response[Object.keys(response)[Object.keys(response).length - 1]] // get the data from json obj
// ADD STYLING - DIFFERENT COLORS FOR WHAT IS COMPLETE
var styleContext = {
getColor: function (feature) {
var objectKeys = Object.keys(gidS); // use objectkeys to loop over all the object properties //use it to get the length
for (var i = 0; i < objectKeys.length; i++){
//alert(i);
//////////////////
if(gidS[i][1]=="MT"){
//alert(gidS[i][1]);
return "green";
}
else if(gidS[i][1]=="IRU"){
alert(gidS[i][1]);
return "#780000"; //no images on this line
}
///////////////////////
}
}
};
If I run the script without the if conditions (between the slashes) then I get a correct incremental value of i based on the maximum length of gidS.
But when I include the if statements for some reason the variable i doesn't increment. It remains 0.
EDITED
The getColor function is executed later like this
// define Style
var defaultStyle = new OpenLayers.Style({
fillColor: "${getColor}",
fillOpacity:"1",
strokeColor: "${getColor}",
strokeOpacity: "1",
strokeWidth: 8,
cursor: "pointer",
pointRadius: 8
}, {
context: styleContext
});
What am I doing wrong here?
Thanks a lot.
D.
Capture the color in a variable, for example: color, and return it at the end of the function:
getColor: function (feature) {
var color = '';
var objectKeys = Object.keys(gidS); // use objectkeys to loop over all the object properties //use it to get the length
for (var i = 0; i < objectKeys.length; i++){
if(gidS[i][1]=="MT"){
color = "green";
}
else if(gidS[i][1]=="IRU"){
color = "#780000"; //no images on this line
}
}
return color;
}
By looping through every property of the object, and then returning, you're effectively getting the last possible matching "MT" or "IRU", if any. If you return out of the function as soon as you find a match, then your getting the first possible matching "MT" or "IRU".
For example, given the set: [[435,'IRU'],[34324,'MT'],[343,'MT']] My method will return green, and your method will return #780000.
don't use the return, it immediately stop after used .
try this altough i dont know the gidS.
if(gidS[i][1]=="MT"){
gidS[i]['color']='green';
}
else if(gidS[i][1]=="IRU"){
gidS[i]['color']='#780000';
}

Give structure to 'random' function js?

I have an array and a function that picks randomly elements from this array and displays them in a div.
My array:
var testarray = [A, B, C, D, E, F];
Part of the js function:
var new_word = testarray[Math.floor((Math.random()*testarray.length)+1)];
$("#stimuli").text(new_word);
My question is, is there a way I can have them picked randomly in a certain ratio/order?
For example, that if I have my function executed 12 times, that each of the six letters is displayed exactly twice, and that there can never be the same letter displayed twice in a row?
You might want to try a quasi-random sequence. These sequences have the properties you're after. http://en.wikipedia.org/wiki/Low-discrepancy_sequence
Edit:
To your question in the comment: Of course there are hundreds ways to solve a problem. Think about using artificial intelligence, a mathematical algorithm or the answers given by others here. It depends on what you really want to achieve. I just gave a robust solution that is easy to understand and implement..
Here's another (different approach), same result but with the prevention that values displays twice in a row.
Jsfiddle: http://jsfiddle.net/kychan/jJE7F/
Code:
function StructuredRandom(arr, nDisplay)
{
// storage array.
this.mVar = [];
this.previous;
// add it in the storage.
for (var i in arr)
for (var j=0; j<nDisplay; j++)
this.mVar.push(arr[i]);
// shuffle it, making it 'random'.
for(var a, b, c = this.mVar.length; c; a = Math.floor(Math.random() * c), b = this.mVar[--c], this.mVar[c] = this.mVar[a], this.mVar[a] = b);
// call this when you want the next item.
this.next = function()
{
// default value if empty.
if (this.mVar.length==0) return 0;
// if this is the last element...
if (this.mVar.length==1)
{
// we must give it..
return this.mVar.pop();
// or give a default value,
// because we can't 'control' re-occuring values.
return -1;
}
// fetch next element.
var element = this.mVar.pop();
// check if this was already given before.
if (element==this.previous)
{
// put it on top if so.
this.mVar.unshift(element);
// call the function again for next number.
return this.next();
}
// set 'previous' for next call.
this.previous = element;
// give an element if not.
return element;
};
}
NOTE: In this example we can't fully control that the same values are displayed twice.. This is because we can control the first numbers, but when there is only one number left to display, we must either give it or display a default value for it, thus there is a chance that the same value is shown.
Good luck!
Like this?
var arr = [1,2,3,4,5,6,7], // array with random values.
maxDispl = 2, // max display.
arr2 = init(arr) // storage.
;
// create object of given array.
function init(arr)
{
var pop = [];
for (var i in arr)
{
pop.push({value:arr[i], displayed:0});
}
return pop;
}
// show random number using global var arr2.
function showRandom()
{
// return if all numbers has been given.
if (arr2.length<1) return;
var randIndex= Math.floor(Math.random()*arr2.length);
if (arr2[randIndex].displayed<maxDispl)
{
document.getElementById('show').innerHTML+=arr2[randIndex].value + ', ';
arr2[randIndex].displayed++;
}
else
{
// remove from temp array.
arr2.splice(randIndex, 1);
// search for a new random.
showRandom();
}
}
// iterate the function *maxDispl plus random.
var length = (arr.length*maxDispl) + 2;
for (var i=0; i<length; i++)
{
showRandom();
}
jsfiddle: http://jsfiddle.net/kychan/JfV77/3/

Categories