Currently when I console.log(deckOfCards), it is returning
all 52 cards, each with a suit, value, and points assigned to them.
{ suit: '♦', value: 'A', points: 11 }
{ suit: '♦', value: 2, points: 2 }
{ suit: '♦', value: 3, points: 3 }
.....
Now, I want to remove one card that has the suit, value and points from my deckOfCards array and return that.
{ suit: '♦', value: 'A', points: 11 }
This is to simulate dealing one card from the deck.
I have tried accessing each index of the array and adding them to the card variable, but it gave me an undefined for index 2.
For loops only return one array of suits and not the others.
I have changed the deckOfCards into an object that has the suit, value, and points in it.
My card constant is where I want to pull one card from the deck.
const suits = ["♦", "♣", "♥", "♠"];
const values = ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"];
for (const suit of suits) {
for (const value of values) {
let points = parseInt(value);
if(value === "J" || value === "Q" || value === "K") points = 10;
if(value === "A") points = 11;
const deckOfCards = {suit, value, points};
const card = deckOfCards
}
}
EDIT TRYING TO ADD NEW METHOD
I'm trying to add two cards each to the player/dealer hands,
but when i log it:
[ { suit: '♠', value: 'A', points: 11 } ]
[ { suit: '♠', value: 'A', points: 11 },
{ suit: '♦', value: 10, points: 10 } ]
Why am I getting 3 objects returned instead of 2?
const dealRandomCard = () => {
return deckOfCards.splice(Math.floor(Math.random() *
deckOfCards.length), 1)[0];
}
// console.log(dealRandomCard());
//////////////////////////////////////////////////////////////
for (let i = 0; i <= 1; i++) {
playerHand.push(dealRandomCard());
dealerHand.push(dealRandomCard());
console.log(playerHand);
// console.log(dealerHand);
}
You could use a single combined object to the result set. And an object for a shorter way of getting the points.
var suits = ["♦", "♣", "♥", "♠"],
values = ["A", 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"],
cards = [],
suit,
value,
points = { A: 11, J: 10, Q: 10, K: 10 };
for (suit of suits) {
for (value of values) {
cards.push({ suit, value, points: points[value] || value });
}
}
function getCard() {
return cards.splice(Math.floor(Math.random() * cards.length), 1)[0];
}
console.log(getCard());
console.log(getCard());
console.log(getCard());
console.log(cards);
Related
Let's say I have an array of objects that contain information about all the exams submitted during a period of time. It's structure's like this:
[
{ name: 'Freddy', grade: 10, date: '20/07/2022' },
{ name: 'Jose', grade: 8, date:'20/07/2022' },
{ name: 'Freddy, grade: 8', date: '25/07/2022' },
{ name: 'Daniel', grade: 5, date: '21/07/2022' },
{ name: 'Jose', grade: 5 }, date: '22/07/22',
]
What I need is to ignore the date value and just calculate the average grade of each student and get a simple array like this:
[9, 6.5, 5]
Now let's say I want the array to follow a specific order so how can I rearrange it following this order: Freddy -> Jose -> Daniel ?
It seems kind of weird but I kind of need the output to be like this in order to use it as a dataset for Chart.js later on.
To do this:
I used reduce to create a dictionary that has each student's grade sum and grade count.
I used a dictionary because it makes it easy to search through it while reduce iterates through the array.
Then I used Object.keys() to get an array of the dictionarie's keys and map-ed that array into an array that has an object for each student's average grade.
I did it this way because I assumed that this output could be useful. It would have been simpler to loop over the dictionary and convert it to a dictionary of averages.
Then we map the array of objects to just the averages.
const students = [
{ name: 'Freddy', grade: 10, date: '20/07/2022' },
{ name: 'Jose', grade: 8, date:'20/07/2022' },
{ name: 'Freddy', grade: 8, date: '25/07/2022' },
{ name: 'Daniel', grade: 5, date: '21/07/2022' },
{ name: 'Jose', grade: 5 , date: '22/07/22'}
]
const grouped = students.reduce(
(output, student) => {
const name = student.name
if (output[name]) {
output[name].gradeTotal += student.grade;
output[name].count += 1;
}
else {
output[name] = {
gradeTotal: student.grade,
count: 1
}
}
return output
}, {})
console.log('Grouped by student: ', grouped)
const studentAverages = Object.keys(grouped).map(name => (
{
name,
average: grouped[name].gradeTotal / grouped[name].count
}
)
)
console.log('Student averages: ', studentAverages)
const justAverages = studentAverages.map(student => student.average)
console.log('Just averages:', justAverages)
I think that what you want.
I made some variables for sum, counter to count the occurrence of each name, average and avgArr to store the averages
Then made nested loops. The outer loop to take each object name and store it in the name variable. The inner loop loop through the array, search for the name and calculate the average for each person. Then add this average to the avgArr array.
I added checked property to each object to avoid taking the same object more than one time if it's true skip that object, if the object doesn't have this property take this object, add the checked property and set it to true. If you don't want this property you can remove it later.
let arr =[
{ name: 'Freddy', grade: 10, date: '20/07/2022' },
{ name: 'Jose', grade: 8, date:'20/07/2022' },
{ name: 'Freddy', grade: 8, date: '25/07/2022' },
{ name: 'Daniel', grade: 5, date: '21/07/2022' },
{ name: 'Jose', grade: 5 , date: '22/07/22' }];
let sum = 0;
let counter = 0;
let avg;
const avgArr = [];
for (const i of arr){
let name = i.name;
if (i.checked === true) {
continue;
}
for (const j of arr){
if (name === j.name) {
j.checked = true;
sum += j.grade;
counter +=1;
}
}
avg = sum / counter;
avgArr.push(avg);
sum = counter = 0;
}
console.log(avgArr); // [9, 6.5, 5]
So I have a function that when passed the parameters id (location of element), marker (updated value requested), array (nested array) it should run through a loop to match the id with the correct nested location.
It should then take the nested location and find those elements on the nested array to update it with the requested value. Though when I attempt to get it to update the value and test its working, all I am receiving in the terminal is the location of the element and not an updated array.
Am I doing something wrong with updating the nested array? This is the code
function BoardManipulation(id, marker, array) {
let match;
for (let i = 0; i < translation.length; i++) {
if(JSON.stringify(translation[i].id) === JSON.stringify(id)) {
match = translation[i].value;
return match
}
}
let newArr = array[match[0]][match[1]] = marker;
console.log(newArr)
}
let board = [["X", "O", "X"], ["X", "O", "_"], ["_", "X", "_"]];
const game = BoardManipulation(7, 'O', board);
console.log(game)
This is the translation piece that the id is checked against.
let translation = [
{ id: 0, value: [0, 0] },
{ id: 1, value: [0, 1] },
{ id: 2, value: [0, 2] },
{ id: 3, value: [1, 0] },
{ id: 4, value: [1, 1] },
{ id: 5, value: [1, 2] },
{ id: 6, value: [2, 0] },
{ id: 7, value: [2, 1] },
{ id: 8, value: [2, 2] },
];
Hello can somebody help me with javascript. I have list of ages store in age.
age = [5, 5, 13, 5, 13];
The sumAge to count duplicate ages.
sumAge = age.reduce((acc, datum) => {
let count= acc[datum];
acc[datum] = count === undefined ? 1 : ++count;
return acc;
}, {});
console.log(sumAge);
I want to get my result to be like this:
{
age:5,
value: 3
},
{
age:13,
value: 2
}
Instead of this.
{
5: 3 ,
13: 2
}
I want to get my result to be like this
The structure in the question is invalid unless you mean you want an array.
Assuming you want an object keyed by the age (but keep reading if you do want an array):
const age = [5, 5, 13, 5, 13];
const sumAge = age.reduce((acc, datum) => {
let entry = acc[datum];
if (entry) {
++entry.count;
} else {
acc[datum] = {age: datum, count: 1};
}
return acc;
}, {});
console.log(sumAge);
But, this isn't really a use case for reduce, it's overcomplicated. Just use a simple for-of loop:
const age = [5, 5, 13, 5, 13];
const sumAge = {};
for (const datum of age) {
let entry = sumAge[datum];
if (entry) {
++entry.count;
} else {
sumAge[datum] = {age: datum, count: 1};
}
}
console.log(sumAge);
If you do want an array, then as Rajesh points out, just use Object.values on the result:
const age = [5, 5, 13, 5, 13];
const sumAge = {};
for (const datum of age) {
let entry = sumAge[datum];
if (entry) {
++entry.count;
} else {
sumAge[datum] = {age: datum, count: 1};
}
}
console.log(Object.values(sumAge));
Using Object.values
let age = [5, 5, 13, 5, 13];
let sumAge = age.reduce((acc, datum) => {
acc[datum] = acc[datum] || { age: datum, value: 0 };
acc[datum].value += 1;
return acc;
}, {});
console.log(Object.values(sumAge));
You could get entries of sumAge and map them as needed
let age = [5, 5, 13, 5, 13];
let sumAge = age.reduce((acc, datum) => {
let count= acc[datum];
acc[datum] = count === undefined ? 1 : ++count;
return acc;
}, {});
let arrAge = Object.entries(sumAge).map(([k,v])=>({age: Number(k), count: v}))
console.log(arrAge);
My reduce has a blank array as the initial value - this becomes the array accumulator. If the object with the key age for the is in the array, the key value is incremented by 1. Otherwise, the object for the key age with initial key value of one is added to the array accumulator. Here's my code
const checkAge = (acc, num) => acc.find(elem => elem.age == num);
const arr = [5, 15, 5, 5, 15].reduce((acc,num) => {
let idx = acc.indexOf(checkAge(acc, num))
if(idx >= 0) acc[idx].value += 1;
else acc.push({age: num, value: 1});
return acc;
}, []);
console.log(arr); //returns [{age: 5, value: 3}, {age:13, value: 2}]
I am running into a truly perplexing bug that I've been unsuccessfully trying to squash for the past several hours.
I am working on a Poker implementation. Initially, I generate the cards with an iterative loop.
const suits = ['Heart', 'Spade', 'Club', 'Diamond'];
const cards = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
const VALUE_MAP = {
2:1,
3:2,
4:3,
5:4,
6:5,
7:6,
8:7,
9:8,
10:9,
J:10,
Q:11,
K:12,
A:13,
};
const generateDeckOfCards = () => {
const deck = [];
for (let suit of suits) {
for (let card of cards) {
deck.push({
cardFace: card,
suit: suit,
value: VALUE_MAP[card]
})
}
}
return deck
}
const fullDeck = generateDeckOfCards()
When the round is completed, the player's 2 Private Cards and 5 Community Cards are concatenated into an array and sorted by value (descending):
player.showDownHand.hand = player.cards.concat(state.communityCards);
hand = player.showDownHand.hand.sort((a,b) => b.value - a.value);
console.log(hand)
// Output:
0: Object { cardFace: "J", suit: "Heart", value: 10, … }
1: Object { cardFace: "9", suit: "Heart", value: 8, … }
2: Object { cardFace: "9", suit: "Club", value: 8, … }
3: Object { cardFace: "6", suit: "Heart", value: 5, … }
4: Object { cardFace: "5", suit: "Diamond", value: 4, … }
5: Object { cardFace: "4", suit: "Diamond", value: 3, … }
6: Object { cardFace: "3", suit: "Club", value: 2, … }
length: 7
Now, the bug occurs when I initiate my method to build the best possible hand of 5 cards depending on hand rank. I need to mess around with this array and possibly mutate it, filter out cards that I've picked out, etc. - So I create a deep clone of the object.
There is a huge problem - the values for the cards CHANGE for some reason! I do not mutate anything in between - The value should be static and derived from the current card's cardFace property.
import { cloneDeep } from 'lodash';
let mutableHand = cloneDeep(hand);
console.log(mutableHand)
// Output
0: Object { cardFace: "J", suit: "Heart", value: 13, … }
1: Object { cardFace: "9", suit: "Heart", value: 8, … }
2: Object { cardFace: "9", suit: "Club", value: 8, … }
3: Object { cardFace: "6", suit: "Heart", value: 6, … }
4: Object { cardFace: "5", suit: "Diamond", value: 4, … }
5: Object { cardFace: "4", suit: "Diamond", value: 3, … }
6: Object { cardFace: "3", suit: "Club", value: 2, … }
Card 0 and 3 have had their values totally changed! Why? I have no idea - Has the original context of the lookup table changed? If anyone has any hints to how I can fix this, I would be most appreciative.
An additional note - Creating a Shallow Copy with
let mutableHand = [...hand]; does NOT initially exhibit this behavior in console log - If I do nothing to it.. However, after I run the shallow copied array through the function, even the original descending deck state has many of its values mutated. Again, I'm not sure why :\
Full code can be viewed on codesandbox.io/s/oqx8ooyv29 - The problem stems from the buildBestHand() function in src/utils/card.js
Here is the problem code:
const bestHand = [];
let mutableHand = cloneDeep(hand);
for (let i = 0; i < 2; i++) {
const indexOfPair = mutableHand.findIndex(card => card.cardFace === frequencyHistogramMetaData.pairs[0].face);
bestHand.push(mutableHand[indexOfPair])
mutableHand = mutableHand.filter((card, index) => index !== indexOfPair)
}
return bestHand.concat(mutableHand.slice(0, 3))
I am trying to find the index of card which matches "Pair" (Player has 2 cards with that face), Push to an array of best cards, filter out that index in between iterations, and fill the rest of the best-cards array with their next 3 highest cards.
Edit: If I do hand = cloneDeep(player.showDownHand.hand).sort((a,b) => b.value - a.value);, the issue is heavily exacerbated, and almost all the values are corrupt for final comparisons
Looking through your example code, you are mutating the value in cards.js:787 (which looks accidental).
} else if ((cur.card.value = highValue)) {
acc.push(cur.name);
console.log(
"Adding player at comparatorindex ",
index,
"To Winners Array"
);
console.log(acc);
return acc;
}
I would recommend using something like eslint, which should warn you against this particular kind of accident.
var foo = { "a": [1,2,3] }
var bar = { "b": [7,8,9] }
output should look like this
[ {a: 1, b: 7}, {a: 2, b: 8}, {a:3, b: 9}]
How can I do this using ramda or javascript functional programming ?
I have done this using for loop i = 0, is it possible using functional ramda programming
If both arrays are always the same length, you can do this using map.
function mergeArrays(arr1, arr2) {
return arr1.map(function(item, index) {
return {
a: arr1[index], //or simply, item
b: arr2[index]
};
});
}
var a = [1, 2, 3];
var b = [7, 8, 9];
var joined = mergeArrays(a, b);
document.getElementById('result').innerHTML = JSON.stringify(joined, null, 2);
<pre id="result">
</pre>
You can achieve this using R.transpose to convert an array of [[1,2,3], [7,8,9]] to [[1, 7], [2, 8], [3, 9]] and then map over it with R.zipObj.
const fn = R.compose(
R.map(R.zipObj(["a", "b"])),
R.transpose
)
const a = [1, 2, 3], b = [7, 8, 9]
const result = fn([a, b])
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
If you would prefer to pass a and b as two arguments to fn rather than an array then you can swap R.transpose in the example above with R.unapply(R.transpose).
Assuming you want [{a:1,b:7},{a:2,b:8},{a:3,b:9}] it can be done pretty easily with map using the index to get the value in b:
var result = a.map((v, i) =>({ a: v, b: b[i] }));
i am having an array
const peopleObject = { "123": { id: 123, name: "dave", age: 23 },
"456": { id: 456, name: "chris", age: 23 }, "789": { id: 789, name:
"bob", age: 23 }, "101": { id: 101, name: "tom", age: 23 }, "102":
{ id: 102, name: "tim", age: 23 } }
for this particular i have created a code that convrts array to object i hope this is usefull for you
const arrayToObject = (array) =>
array.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {})
const peopleObject = arrayToObject(peopleArray)
console.log(peopleObject[idToSelect])
Your expected output doesn't have a valid format. You should store the data in array. Like ,
var output = [];
var a = [1,2,3], b = [7,8,9];
for(var i=0; i< a.length; i++){
var temp = {};
temp['a'] = a[i];
temp['b'] = b[i];
output.push(temp);
}
You cannot store the result in an object the way you want. Objects are key-value pairs. But what you expect is only the values without keys which is not possible!
create function form ramda's addIndex and map
const data = { keys: ['a', 'b', 'c'], values: ['11', '22', '33'] }
const mapIndexed = R.addIndex(R.map)
const result = mapIndexed((item, i) => {
return { [item]: data.values[i] }
}, data.keys)
You will get an array of objects