Key inside map() of an object not working [duplicate] - javascript

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 4 months ago.
I've an object showing genres with their counts. It looks like this.
const totalGenresWatchedCount = {
"Comedy": 3,
"Romance": 2,
"Adventure": 1,
"Science Fiction": 1,
"Action": 2,
"Drama": 1,
"Family": 1,
"Crime": 1,
"Thriller": 1
}
I also have another array containing all the genres listed.
const totalUniqueGenresWatched = ["Comedy", "Romance", "Adventure", "Science Fiction", "Action"].
What I want to achieve is get all the genre and the count printed together. Ive tried with the this code.
totalUniqueGenresWatched.map((genre) => {
return (
<p>
{genre} - {totalGenresWatchedCount.genre}
</p>
);
})
I cant seem to print the object value from the genre key, if I remove the first genre VS Code IntelliSense predicts that the key is not even getting used. Am i missing anything?

One way to iterate over objects, like your totalGenresWatchedCount, is to convert the object key and value to an array with Object.entries and thereafter put the resulting array into a map, like your own example and return the HTML your would like.
Note that Object.entries gives you back an array with [key, value], that I renamed in my example to [genre, count] to have precise variable names
const totalGenresWatchedCount = {
Comedy: 3,
Romance: 2,
Adventure: 1,
"Science Fiction": 1,
Action: 2,
Drama: 1,
Family: 1,
Crime: 1,
Thriller: 1,
};
const myHtmlElements = Object.entries(totalGenresWatchedCount).map(
([genre, count]) => {
return (
<p>
{genre} - {count}
</p>
);
}
);

totalGenresWatchedCount.genre refers to "genre" key in totalGenresWatchedCount
but you don't have "genre" key in totalGenresWatchedCount instead you have "Comedy", "Romance", etc...
change totalGenresWatchedCount.genre to totalGenresWatchedCount[genre]
and by the way you should not blank space in the key... like "Science Fiction"
modify it to "Science_Fiction"

Various ways to achieve this more cleanly. Object.entries() comes to mind:
const totalGenresWatchedCount = {
Comedy: 3,
Romance: 2,
Adventure: 1,
'Science Fiction': 1,
Action: 2,
Drama: 1,
Family: 1,
Crime: 1,
Thriller: 1,
};
const html = [];
for (const [key, value] of Object.entries(totalGenresWatchedCount)) {
html.push(
<li>
{key}: {value}
</li>
);
}
Of course, this is assuming you're project includes a compiler for JSX.
You can read about the Object.entries() method here:
MDN Object.entries()

Related

Remove duplicate items from the array retracted from api

I am building a Blog app and I am trying to get results but it is showing duplicate results, I am trying to remove the duplicate results from the array.
But the problem is there are two key and values in each dict inside array, One is unique and other can be same so I am trying to distinct based on same array, It worked But the other key and value pair (which is unique) is not attaching with the other pair.
response which is returning from db
[
{
"id": 2,
"name": "user_1"
},
{
"id": 3,
"name": "user_3"
},
{
"id": 4,
"name": "user_3"
}
]
App.js
function App() {
const [blogs, setBlogs] = useState([]);
axios.get("retract_blogs/").then((res) => {
// Here I also want to attach "id"
setBlogs({[...new Set(res.data.data.map(x => x.name))]})
}
return(
<div>
{
blogs.map((user) =>
<div>
{user.name}
// Here I wamt to show ID
// {user.id}
</div>
}
</div>
)
}
I want to add id with x.username, I also tried using
setBlogs({data:[...new Set(res.data.data.map(x => x.name, x.id))]})
But it showed
x is not defined
But I am trying to add both name and id, and remove duplicates based on name not id.
I have tried many times but it is still not working.
To keep the id of the last occurence you can create a Map of the array keyed by name and then convert back to an array using the iterator returned by Map.values(). This works by overwriting earlier entries in the Map with the same name.
const users = [{ "id": 2, "name": "user_1" }, { "id": 3, "name": "user_3" }, { "id": 4, "name": "user_3" }];
const result = [...new Map(users.map((user) => [user.name, user])).values()];
console.log(result);
// [ { id: 2, name: 'user_1' }, { id: 4, name: 'user_3' } ]
If you instead want to keep the id of the first occurence of a name you can use a slightly modified 'group by' grouping into an object by name (here in a reduce() call, but it could easily be done in a standard loop as well) before taking the Object.values. This works by only setting the accumulator[name] property if it doesn't already exist, here using logical nullish assignment (??=)
const users = [{ "id": 2, "name": "user_1" }, { "id": 3, "name": "user_3" }, { "id": 4, "name": "user_3" }];
const result = Object.values(users.reduce((a, c) => (a[c.name] ??= c, a), {}));
console.log(result);
// [ { id: 2, name: 'user_1' }, { id: 3, name: 'user_3' } ]

Combining two objects from two different arrays

I have two arrays, orders and cartitems
I want to create a singel payload with information of both of arrays combined. to post to my API using Axios.
I've tried mapping one array (since I only need one item from the other array) and then trying to add the objects together like this:
const payload = []
let newArray = []
this.props.cartItems.map((item) => {
let payloadobject = {
productName: item.productname,
amount: item.qty,
price: item.price,
order_id: this.props.cart.id,
}
newArray = appendObjTo(payload, payloadobject);
})
Hoping newArray would hold the combined combined array. But get met with the error:
can't find variable: appendObjTo
How do I combine both objects? That are each in side of their own array
edit
current data structure
catritems
cartItems Array [
Object {
"id": 2,
"price": "6.50",
"productname": "Baco",
"qty": 2,
}
]
orders
orders Array [
Object {
"id": 2,
}
]
desired output
newArray Array [
Object {
"id": 2,
"price": "6.50",
"productname": "Baco",
"qty": 2,
"order_id": 1 (hold id from order object),
}
]
You get the error message since appendObjTo isn't defined. It's not a standard function, and if you've defined it yourself it's probably in another scope.
Instead of appendObjTo you could use the Object.assign function (MDN Reference). It could be used like this:
newArray = Object.assign({}, payload, payloadobject);
However, there's another fault in your code. Right now your assigning each combined object to newArray, and at the en it will hold the last combined object, not an array.
The lambda function you supply to map should return a new object that you want to replace the input object in the new array. When all objects are looped through the map function returns a new array (MDN Reference). In your case it could be used like this:
const payload = [];
let newArray = this.props.cartItems.map((item) => {
let payloadobject = {
productName: item.productname,
amount: item.qty,
price: item.price,
order_id: this.props.cart.id
};
return Object.assign({ }, payload, payloadobject);
});
This will make newArray be an array of object where each object is a combination of the whole payload, and payloadobject.
Hope this helps 😊

Filter highest numbers out of an object

I have the following object, with points per sport for an individual person. This information comes out of a database, based on the search for "Jack Miller"
Jdata = {
"name": "Jack Miller",
"sports": {
"Basketball": 2,
"Football": 3,
"Iceskating": 5,
"Running": 4,
}
}
I would like to display the top 2(3) sports for the name on my HTML page. Do to that, I was thinking to extract the information into an array like this:
SportVal = [];
SportNames = [];
for(var key in this.Jdata.sports){
if(!this.Jdata.sports.hasOwnProperty(key)){
continue;
}
this.SportVal.push(this.Jdata.scores[key]);
this.SportNames.push(key)
}
Then I would have to sort the SportVal array in descending order and can use e.g. ngFor in the HTML to display the results.
However, how would I get back the corresponding Names? Also I don't think this is the most effective way, since I run into a problem if scores are equal. So do you maybe have a better idea how to do this?
You could use Array.prototype.sort() to do it.
Jdata = {
"name": "Jack Miller",
"sports": {
"Basketball": 2,
"Football": 3,
"Iceskating": 5,
"Running": 4,
}
}
const sorted = Object.entries(Jdata.sports)
.sort((a, b) => b[1] - a[1])
.slice(0, 3)
.map((pair) => pair[0]);
console.log(sorted);

map an array from an array of objects key/value

I need to take an array objects that and map it so that the new array is just a simple array if each object's id.
So for example:
[
{id: 49, name: "Rest update test"},
{id: 12, name: "Rest test"}
]
would become:
[49, 12]
i have tried this so far:
myObject.map(object => object.id);
so my actual function that is not working is the following, when I view the console.log, it is showing the original object:
onSubmit() {
this.userForm.value.accountsToAdd.map(object => object.id);
console.log(this.userForm.value.accountsToAdd);
}
Assuming the given code does not work, then you need to assign the result of mapping.
Array#map does not mutate the original array but return a new one.
var array = [{ id: 49, name: "Rest update test" }, { id: 12, name: "Rest test" }],
ids = array.map(object => object.id);
console.log(ids);

How to store multiple key value, where value is an array of elements in javascript?

I am looking for a quick way to crate a key values pair in JavaScript, where I have a key it's an ID, like 1, 2, 3, 4, 5, .... 100 and the values are an array composed by a reference, name and quantity.
Is this an appropriate syntax?
var petfoodRefData = {
"1": [
{"ref":5222, "description":"purina", "qtt":500},
{"ref":5322, "description":"hills", "qtt":500},
{"ref":6222, "description":"hills junior", "qtt":500}
],
"2": {"ref":8022, "description":"fatcat", "qtt":60}
}
Is there an easier better way to do this? I basically want to for every ID = 1 give me all pet food references, and add them to the document.
You're close:
var petfoodRefData = {
"1": [
{"ref":5222, "description":"purina", "qtt":500},
{"ref":5322, "description":"hills", "qtt":500},
{"ref":6222, "description":"hills junior", "qtt":500}
],
"2": [{ "ref":8022, "description":"fatcat", "qtt":60} ]
};
Use [] for arrays.

Categories