Get random array element where value not equal - javascript

I have an array:
arr = ["blue", "red", "green"];
How can I get a random element from the array except the element with value "red"?
I know I an use the following to get a random array element but how do I put a "where/if" statement?

The code that is guaranteed to complete would look like this:
var arr = ["blue", "red", "green"];
var onlyValidValues = arr.filter(v => v !== 'red');
if (onlyValidValues.length === 0) {
throw new Error('empty array');
}
var randomItem = onlyValidValues[Math.floor(Math.random() * onlyValidValues.length)];
So compared to other suggestions it only picks random values from an array cleaned from the "forbidden" elements.

Use Math.random() within a while loop
var arr = ["blue", "red", "green"],
val = 'red';
while (val == 'red')
val = arr[Math.floor(Math.random() * arr.length)]
console.log(val);
Or copy the array and remove red from it, then get an element
var arr = ["blue", "red", "green"],
arrNew = arr.slice(0); // copy the array
arrNew.splice(arr.indexOf('red'), 1); // remove red from it
val = arrNew[Math.floor(Math.random() * arrNew.length)] //get random element
console.log(val);
In case there is multiple red elements in array, then use filter() as in #zerkms answer.

You could do something like this:
arr = ["blue", "red", "green"];
getRandomChoice = function(arr) {
var choice = arr[Math.floor(Math.random()*arr.length)];
while (choice === "red") {
choice = arr[Math.floor(Math.random()*arr.length)];
}
return choice;
}
getRandomChoice(arr)

This may be useful..
var arr = ["blue", "red", "green"];
var item = arr[Math.floor(Math.random()*arr.length)];
while(item == "red"){
item = arr[Math.floor(Math.random()*arr.length)];
}
document.write(item)
Hope it helps to solve your problem

I've done a function using new ES6 features.
With my function you can exclude more than one element.
Here's my approach :
const arr = ["blue", "red", "green"];
function getRandomElementExcluding (...excluded){
try {
let random = Math.ceil(Math.random() * arr.length - 1);
if(excluded === undefined)
return arr[random];
else if (excluded.includes(arr[random]))
return getRandomElementExcluding(...excluded);
else
return arr[random];
} catch (e){
return false;
}
}
console.log( getRandomElementExcluding('red') );
// console.log( getRandomElementExcluding('red', 'green', 'blue') ); It will return false;

Related

How can I chose random color from an array?

I've created a random number selecting system but I couldn't figure out how to pick it from the array please help me. Here is my code:
var buttonColours = ["red", "blue", "green", "yellow"];
var randomChosenColour = buttonColours[newSequence];
function newSequence () {
var randomNumber = Math.floor(Math.random() * 4);
}
I have extended your code with a function call and a return statement:
var buttonColours = ["red", "blue", "green", "yellow"];
var randomChosenColour = buttonColours[newSequence()];
function newSequence () {
var randomNumber = Math.floor(Math.random() * 4);
return randomNumber;
}
console.log(randomChosenColour);
Or see a shorter version based on the suggestion:
const buttonColours = ["red", "blue", "green", "yellow"];
const newSequence = () => Math.floor(Math.random() * 4);
const randomChosenColour = buttonColours[newSequence()];
console.log(randomChosenColour);
var randomColor=buttonColours[Math.floor(Math.random()*4)];
or, leaving room for expansion:
var randomColor=buttonColours[Math.floor(Math.random()*buttonColours.length)];
You need to call newSequence to generate the number. and return the randomNumber from the function.
Like this:
var buttonColours = ["red", "blue", "green", "yellow"];
var randomChosenColour = buttonColours[newSequence()];
function newSequence () {
var randomNumber = Math.floor(Math.random() * 4);
return randomNumber;
}
There were two problems, the index selecting a value was not a number, it was a function (because the function was not being called), and secondly the function was creating a number but not returning it.
Hope this helps!
Really all you need is a function to pick a random value, like _.sample from Lodash:
function sample(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
Where that can handle arbitrary arrays of arbitrary length:
sample(buttonColors);
Your newSequence function is way too specific and presumes a lot about the structure of the data. That 4 is a huge liability that needs to be removed.

array.push() method is not adding anything to array and working weirdly

I am new to programming and also stackoverflow.
My problem is related to array.push() method in JavaScript.
See the code first
var buttonColors = ["red", "blue", "green", "yellow"];
var gamePattern = [];
gamePattern = gamePattern.push(nextSequence());
function nextSequence(){
var randomNumber = Math.floor( Math.random() * 4);
var randomChosenColor = buttonColors[randomNumber];
return randomChosenColor;
}
Kindly check this image too...
This is chrome console output
The problem is that the randomNumber is being generated properly and randomChosenColor is also getting the color properly but it is not being pushed in gamePattern array at line number 3. Also help me if there is some alternative to this method.
Push changes the original state of the array. So you don't need to re-initialize the array.
var buttonColors = ["red", "blue", "green", "yellow"];
let temp=[];
temp.push(seq());
console.log(temp);
function seq(){
var randomNumber = Math.floor( Math.random() * 4);
var randomChosenColor = buttonColors[randomNumber];
return randomChosenColor;
}
push() mutates the original array (and returns the new length), so you don't need to assign a new value to gamePattern. Try something like this:
var buttonColors = ["red", "blue", "green", "yellow"];
var gamePattern = [];
gamePattern.push(nextSequence());
function nextSequence(){
var randomNumber = Math.floor(Math.random() * 4);
var randomChosenColor = buttonColors[randomNumber];
return randomChosenColor;
}

how can I use includes() function on nested arrays?

I have an array like this:
var arr = [];
arr = [['red', 685], ['green', 210], ['blue', 65]];
Also I have two variables:
var color = 'blue';
var number = 21;
All I'm trying to do is checking the first item of each nested array of arr and then either update the second item of it or make a new array for it.
Here is some examples:
Input:
var color = 'blue';
var number = 21;
Expected output:
arr = [['red', 685], ['green', 210], ['blue', 21]];
Input:
var color = 'yellow';
var number = 245;
Expected output:
arr = [['red', 685], ['green', 210], ['blue', 21], ['yellow', 245]];
Here is what I've tried so far:
if ( !arr.includes(color) ) {
arr.push([color, number]);
} else {
arr[color] = time;
}
But !arr.includes(color) condition is wrong. Because each item of arr is also an array. Anyway, how can I use includes() function on the first item of nested arrays?
You cannot directly use includes on nested array, however, you can use find on array.
arr.find(el => el[0] === color)
This will return the element of array found else undefined. The returned value can be used to update the second element in the array.
var arr = [
['red', 685],
['green', 210],
['blue', 65]
];
var color = 'blue';
var number = 21;
function upsert(array, color, number) {
var exists = arr.find(el => el[0] === color);
if (exists) {
exists[1] = number;
} else {
arr.push([color, number]);
}
}
upsert(arr, color, number);
console.log(arr);
var color = 'yellow';
var number = 245;
upsert(arr, color, number);
console.log(arr);
Simply iterate the array and update the value if found, else push a new value
Demo
var arr = [['red', 685], ['green', 210], ['blue', 65]];
console.log(updateArray(arr, 'blue', 21));
function updateArray(arr, color, value)
{
var isFound = false;
arr = arr.map( function(item){
if( item[0] == color )
{
isFound = true;
item[1] = value;
}
return item;
});
if ( !isFound )
{
arr.push([color, value]);
}
return arr;
}
You should make a loop that cycles through the array because, as you pointed out yourself, each element of the array is itself an array.
If you do:
for(let i = 0; i < arr.length; i++){
if ( !arr[i].includes(color) ) {
arr.push([color, number]);
} else {
arr[i][1] = time;
}
}
This way you are checking if the array at position i has the color, if it doesn't you push a new array into the array, otherwise you change the array value at index 1 of the array i

Creating complex objects dynamically in javascript

Is it possible to create complex objects at runtime in javascript ? If so, what is the correct syntax ?
var food = {};
food["fruit"]["yellow"] = "banana";
food["meat"]["red"] = "steak";
food."fruit"."green" = "apple";
It's not clear what you're trying to do. If you want to build that object up all at once, then you could do something like:
var food = {
fruit: {
yellow: 'banana',
green: 'apple'
},
meat: {
red: 'steak'
}
};
If you need to piece it together one nested object at a time, then you just need to make sure that you are creating a new object to add properties to.
For example, your line:
food["fruit"]["yellow"] = "banana";
will probably fail because food.fruit does not exist.
You should do:
var food = {};
food.fruit = {};
food.fruit.yellow = 'banana';
You could write a function to add data to your object.
e.g.
function addEntry(obj, entry) {
if(entry.length < 2) return;
if(entry.length === 2) obj[entry[0]] = entry[1];
else {
if(!obj[entry[0]] || typeof obj[entry[0]] !== "object") obj[entry[0]] = {};
addEntry(obj[entry[0]], entry.slice(1));
}
}
var data = [
["fruit", "yellow", "banana"],
["meat", "red", "steak"],
["fruit", "green", "apple"]
];
var obj = {};
for(var i = 0; i < data.length; i++) {
addEntry(obj, data[i]);
}
console.log(obj);

The best way to remove array element by value

I have an array like this
arr = ["orange","red","black","white"]
I want to augment the array object defining a deleteElem() method which acts like this:
arr2 = arr.deleteElem("red"); // ["orange","black","white"] (with no hole)
What is the best way to accomplish this task using just the value parameter (no index)?
Here's how it's done:
var arr = ["orange","red","black","white"];
var index = arr.indexOf("red");
if (index >= 0) {
arr.splice( index, 1 );
}
This code will remove 1 occurency of "red" in your Array.
Back when I was new to coding I could hardly tell what splice was doing, and even today it feels less readable.
But readability counts.
I would rather use the filter method like so:
arr = ["orange","red","black","white","red"]
arr = arr.filter(val => val !== "red");
console.log(arr) // ["orange","black","white"]
Note how all occurrences of "red" are removed from the array.
From there, you can easily work with more complex data such as array of objects.
arr = arr.filter(obj => obj.prop !== "red");
There is an underscore method for this, http://underscorejs.org/#without
arr = ["orange","red","black","white"];
arr = _.without(arr, "red");
The trick is to go through the array from end to beginning, so you don't mess up the indices while removing elements.
var deleteMe = function( arr, me ){
var i = arr.length;
while( i-- ) if(arr[i] === me ) arr.splice(i,1);
}
var arr = ["orange","red","black", "orange", "white" , "orange" ];
deleteMe( arr , "orange");
arr is now ["red", "black", "white"]
Array.prototype.deleteElem = function(val) {
var index = this.indexOf(val);
if (index >= 0) this.splice(index, 1);
return this;
};
var arr = ["orange","red","black","white"];
var arr2 = arr.deleteElem("red");
My approach, let's see what others have to say. It supports an "equals" method as well.
// Remove array value
// #param {Object} val
Array.prototype.removeByValue = function (val) {
for (var i = 0; i < this.length; i++) {
var c = this[i];
if (c == val || (val.equals && val.equals(c))) {
this.splice(i, 1);
break;
}
}
};
Read https://stackoverflow.com/a/3010848/356726 for the impact on iterations when using prototype with Array.
Or simply check all items, create a new array with non equal and return it.
var arr = ['orange', 'red', 'black', 'white'];
console.info('before: ' + JSON.stringify(arr));
var deleteElem = function ( val ) {
var new_arr = [];
for ( var i = 0; i < this.length; i++ ) {
if ( this[i] !== val ) {
new_arr.push(this[i]);
}
}
return new_arr;
};
arr = deleteElem('red');
console.info('after: ' + JSON.stringify(arr));
http://jsfiddle.net/jthavn3m/
The best way is to use splice and rebuild new array, because after splice, the length of array does't change.
Check out my answer:
function remove_array_value(array, value) {
var index = array.indexOf(value);
if (index >= 0) {
array.splice(index, 1);
reindex_array(array);
}
}
function reindex_array(array) {
var result = [];
for (var key in array) {
result.push(array[key]);
}
return result;
}
example:
var example_arr = ['apple', 'banana', 'lemon']; // length = 3
remove_array_value(example_arr, 'banana');
banana is deleted and array length = 2
If order the array (changing positions) won't be a problem you can solve like:
var arr = ["orange","red","black","white"];
arr.remove = function ( item ) {
delete arr[item];
arr.sort();
arr.pop();
console.log(arr);
}
arr.remove('red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here you go:
arr.deleteElem = function ( val ) {
for ( var i = 0; i < this.length; i++ ) {
if ( this[i] === val ) {
this.splice( i, 1 );
return i;
}
}
};
Live demo: http://jsfiddle.net/4vaE2/3/
The deleteElem method returns the index of the removed element.
var idx = arr.deleteElem( 'red' ); // idx is 1

Categories

Resources