Return books that contain specific genres - javascript

I want to retrieve the object that contains specific genres based on show variable value
const books=
"genres" : [
"history"
],
"title" : "Yemen",
"published" : NumberInt(1990),
"author" : ObjectId("5ef5fb84b368d90d48e785a1"),
},{"genres" : [
"Web",
"Programming",
"Development"
],
"title" : "JavaScript for Profissional",
"published" : NumberInt(2016),
"author" : ObjectId("5f046ddc4a55f425d86311d0"),},
{"genres" : ["Programming"],
"title" : "CSS for Profissional",
"published" : NumberInt(2019),
"author" : ObjectId("5f046ddc4a55f425d86311d0"),
}
This is the books object.
I want to get the books that contain specific genres
like that
const show="programming"
const booksToShow =
show === "All"
? books
: books.filter((book) => book.genres.map(g=>{
if(g.toLocaleLowerCase()===showAll.toLocaleLowerCase())
return book
}
)
everything executed perfectly but it doesn't return any value into booksToShow while it supposed to return this object
{"genres" : [
"Web",
"Programming",
"Development"
],
"title" : "JavaScript for Profissional",
"published" : NumberInt(2016),
"author" : ObjectId("5f046ddc4a55f425d86311d0"),}
so are there anyway to repair this problem

The second part of your ternary condition can work using some to know if your books contains at least the given genre once :
books.filter(book => book.genres.some(g => g.toLocaleLowerCase() === show.toLocaleLowerCase()))
I have some performance concerns about this solution though. You may want to apply toLocaleLowerCase() to all books either once the data is received or directly within your database to avoid doing this operation every time your component re-renders.
By doing so you will be able to replace some by includes, drastically improving your perfs:
books.filter(book => book.genres.includes(show))

Solution with a double filter:
const books= [{
"genres" : [
"history"
],
"title" : "Yemen",
"published" : 1990,
"author" : "5ef5fb84b368d90d48e785a1"
},{"genres" : [
"Web",
"Programming",
"Development"
],
"title" : "JavaScript for Profissional",
"published" : 2016,
"author" : "5f046ddc4a55f425d86311d0"
},
{"genres" : ["Programming"],
"title" : "CSS for Profissional",
"published" : 2019,
"author" : "5f046ddc4a55f425d86311d0",
}];
const show="programming".toUpperCase();
const booksToShow = show === "All" ? books : books.filter((b) =>
b.genres.filter((g) =>
g.toUpperCase() === show
).length > 0);
console.log(booksToShow);

Related

array in array filter - javascript

hello i need help with array , as you can see my data
{
"age" : "18",
"altKategoriler" : [ "Dramalar" ],
"category" : [ "Aksiyon", "Heyecanlı", "Gerilim" ],
"id" : 5240718100,
"img" : "https://i.ibb.co/k8wx5C8/AAAABW9-ZJQOg-MRljz-Zwe30-JZw-Hf4vq-ERHq6-HMva5-ODHln-Ci-OEV6ir-Rcjt88tcnm-QGQCKpr-K9h-Oll-Ln-Sbb-EI.jpg",
"izlenilmeSayisi" : 0,
"logo" : "https://i.ibb.co/Rb2SrcB/AAAABfcrhh-Rni-Ok-Ct2l-Rys-ZYk-Oi-T0-XTeagkrw-Mkm-U0h-Lr-WIQZHEHg-VXihf-OWCwz-Vv-Qd7u-Ffn-DFZEX2-Ob.webp",
"oyuncuKadrosu" : [ "Diego Luna", "Michael Pena", "Scoot McNairy", "Tenoch Huerta", "Joaquin Cosio" ],
"senarist" : [ "Doug Miro" ],
"time" : "3 Sezon",
"title" : "Narcos: Mexico",
"type" : "Dizi",
"videoDescription" : "Guadalajara Karteli'nin yükselişinin gerçek öyküsünü anlatan bu yeni ve cesur Narcos hikâyesinde, Meksika'daki uyuşturucu savaşının 1980'lerdeki doğuşuna tanıklık edin.",
"videoQuality" : "HD",
"videosrc" : "https://tr.vid.web.acsta.net/uk/medias/nmedia/90/18/10/18/19/19550785_hd_013.mp4",
"year" : "2021",
"yonetmen" : [ "Carlo Bernard", "Chris Brancato" ]
}
I can access elements such as id , title or logo because they are not arrays.
How can I loop through the data inside the array since there is an array in the category in yield?
var data = this.database.filter((item) => item.type == searchType)
var data = this.database.filter((item) => item.category == searchCategory)
It's okay because my type value doesn't have an array.
But when I enter my category value, it only gets the first index[0]. It does not look at other indexes.
in summary,
item.category[0] , item.category[1] , item.category[2]...........
How can I get index browsing like
if your data looks like this :
let data ={
"age" : "18",
"altKategoriler" : [ "Dramalar" ],
"category" : [ "Aksiyon", "Heyecanlı", "Gerilim" ],
"id" : 5240718100,
"img" : "https://i.ibb.co/k8wx5C8/AAAABW9-ZJQOg-MRljz-Zwe30-JZw-Hf4vq-ERHq6-HMva5-ODHln-Ci-OEV6ir-Rcjt88tcnm-QGQCKpr-K9h-Oll-Ln-Sbb-EI.jpg",
"izlenilmeSayisi" : 0,
"logo" : "https://i.ibb.co/Rb2SrcB/AAAABfcrhh-Rni-Ok-Ct2l-Rys-ZYk-Oi-T0-XTeagkrw-Mkm-U0h-Lr-WIQZHEHg-VXihf-OWCwz-Vv-Qd7u-Ffn-DFZEX2-Ob.webp",
"oyuncuKadrosu" : [ "Diego Luna", "Michael Pena", "Scoot McNairy", "Tenoch Huerta", "Joaquin Cosio" ],
"senarist" : [ "Doug Miro" ],
"time" : "3 Sezon",
"title" : "Narcos: Mexico",
"type" : "Dizi",
"videoDescription" : "Guadalajara Karteli'nin yükselişinin gerçek öyküsünü anlatan bu yeni ve cesur Narcos hikâyesinde, Meksika'daki uyuşturucu savaşının 1980'lerdeki doğuşuna tanıklık edin.",
"videoQuality" : "HD",
"videosrc" : "https://tr.vid.web.acsta.net/uk/medias/nmedia/90/18/10/18/19/19550785_hd_013.mp4",
"year" : "2021",
"yonetmen" : [ "Carlo Bernard", "Chris Brancato" ]
}
and if we have array of data you can do something like this :
myArray.filter(item=>item.category.indexOf(searchCategory)>=0)
but if you want to explore in object rather than array you can do this :
data.category.indexOf(searchCategory)>=0
You could make this a bit generic, by testing whether the targeted field is an array, using Array.isArray, and then call a filter on each element, and see if any is positive (using .some()). The filter can be function that is provided, so that it can perform a simple match, or apply a regular expression, or anything else.
Instead of testing with Array.isArray you could skip that step and check whether the value has a .some() method. If so, calling it will give the desired outcome, and otherwise (using the .? and ?? operators), the filter should be applied to the value as a whole:
Here is how that looks:
function applyFilter(data, field, filter) {
return data.filter(item => item[field]?.some(filter) ?? filter(item));
}
// Example use:
var data = [{
"category" : [ "Action", "Thriller", "Horror"],
"type" : "Series",
}, {
"category" : [ "Historical", "Romance" ],
"type" : "Theatre",
}];
// Find entries that have a category that looks like "roman*":
var result = applyFilter(data, "category", value => /^roman.*/i.test(value));
console.log(result);
If you are running on an older version of JavaScript, and don't have support for .? or ??, then use:
return data.filter(item => Array.isArray(item[field])
? item[field].some(filter)
: filter(item));

How to filter firebase data based on timestamp using startAt & endAt

I am trying to filter firebase data using startAt and/or endAt.
My data is structured as below.
{
"notes" : {
"-LOs0Ikx4ydM5RatREM1" : {
"data" : {
"dueDate" : 1561629600000,
"description" : "Korewa nan desuka?!",
"createdAt" : 1539611900000,
"title" : "First "
},
"members" : {
"author" : "1212121212121212121212121212"
}
},
"-LOs0Ikx4ydM5RatREM2" : {
"data" : {
"dueDate" : 4004870448000,
"description": "Test"
"createdAt" : 1539611900000,
"title" : "Second"
},
"members" : {
"author" : "1212121212121212121212121212"
}
},
"-LhBt9msLFKqUQ-koI9W" : {
"data" : {
"dueDate" : 1564653600000,
"description" : "abc",
"createdAt" : 1560363158279,
"title" : "August 1"
},
"members" : {
"author" : "3434343434343434343434343434"
}
},
"-LhBtKdDrQv9eKuYdfCi" : {
"data" : {
"dueDate" : 1564653600000,
"description" : "abcdef",
"createdAt" : 1560363158279,
"title" : "August 2"
},
"members" : {
"author" : "3434343434343434343434343434"
}
}
}
}
What I wish is to fetch all "notes" where dueDate has passed.
const now = moment().valueOf() //Eg. 1561629500000
database.ref('notes/')
.orderByChild("dueDate")
.endAt(now)
.once("value", (snapshot) => {
console.log('Process expired notes')
snapshot.forEach( (data) => {
const obj = data.val()
console.log('Date comparison:', (now >= obj.data.alertDate))
...
The code above does not work, it returns all the objects from the example JSON. The console.log logs "False" for three out of four returned objects.
I could do a comparison and only process the objects that meets my criteria, but that would defeat the purpose.
I have indexed the database on ["notes\data\alertDate"].
What am I missing? I must have misinterpreted the documentation somehow. :)
Your dueDate property is nested under data, so you need to address is as data/dueDate:
database.ref('notes')
.orderByChild("data/dueDate")
You might want to include both a startAt() and endAt() clause, with just a reasonable value for startAt() and the specific value you're already using for endAt().

Find nested property from ember lodash and pick the value

I am new to javascript.
I would like to check whether the specific nested property is present or not in an array of items, ex)
[{
"_id" : ObjectId("5c4ec057e21b840001968d31"),
"status" : "ACTIVE",
"customerId" : "sample-book",
"bookInfo" : {
"bookChunks" : [
{
"key" : "Name",
"value" : "test"
},
{
"key" : "Surname1",
"value" : "testtt"
},
{
"key" : "user-contact",
"value" : "sample-value",
"ContactList" : {
"id" : "sample-id",
"timeStamp" : "Tue, 20 Sep 2016 07:49:25 +0000",
"contacts" : [
{
"id" : "contact-id1",
"name" : "Max Muller",
"phone_number" : "+XXXXXXX"
},
{
"id" : "contact-id2",
"name" : "Max Muller",
"phone_number" : "+XXXXXXX"
}
]
}
}
]
}
},
{
"_id" : ObjectId("5c4ec057e21b840001968d32"),
"status" : "ACTIVE",
"customerId" : "sample-book1",
"bookInfo" : {
"bookChunks" : [
{
"key" : "Name",
"value" : "test"
},
{
"key" : "Surname1",
"value" : "testtt"
}
]
}
}]
Here, I would like to find whether any item has ContactList or contacts present. If it is present take the item and put it in a separate list.
I am using ember-lodash. Using normal javascript or lodash would be fine for me. Any help will be really appreciated.
You could use filter and some. This returns all the objects which have at least one object with ContactList property inside bookInfo.bookChunks array.
const input=[{"_id":"5c4ec057e21b840001968d31","status":"ACTIVE","customerId":"sample-book","bookInfo":{"bookChunks":[{"key":"Name","value":"test"},{"key":"Surname1","value":"testtt"},{"key":"user-contact","value":"sample-value","ContactList":{"id":"sample-id","timeStamp":"Tue, 20 Sep 2016 07:49:25 +0000","contacts":[{"id":"contact-id1","name":"Max Muller","phone_number":"+XXXXXXX"},{"id":"contact-id2","name":"Max Muller","phone_number":"+XXXXXXX"}]}}]}},{"_id":"5c4ec057e21b840001968d32","status":"ACTIVE","customerId":"sample-book1","bookInfo":{"bookChunks":[{"key":"Name","value":"test"},{"key":"Surname1","value":"testtt"}]}}]
const output = input.filter(o =>
o.bookInfo.bookChunks.some(c => "ContactList" in c)
)
console.log(output)
If you just want to check if any of the objects have ContactList, you could replace filter with another some
(Note: This assumes that bookInfo.bookChunks will not be undefined. Otherwise you'd have to add a undefined check before using the nested property)

Push currentUser's ID to inner Array of a collection/ document in meteorjs

{
"_id" : "s2QBCnv6fXv5YbjAP",
"question" : "Is this real change?",
"createdAt" : ISODate("2016-05-13T21:05:23.381Z"),
"yes" : [
{
"heading" : "Yes It is",
"body" : "I think this government knows what they are doing. That's why there has not been any form of protest",
"email" : "I think this government knows what they are doing. That's why there has not been any form of protest",
"createdAt" : ISODate("2016-05-13T21:08:25.119Z"),
"replies" : [ ],
"likes" : [ ]
},
{
"heading" : "Well, Yes",
"body" : "I think this is change as we all want to know what the government is doing and I am grateful to be alive at this time",
"email" : "I think this is change as we all want to know what the government is doing and I am grateful to be alive at this time",
"createdAt" : ISODate("2016-05-13T21:10:47.123Z"),
"replies" : [ ],
"likes" : [ ]
}
],
"no" : [
{
"heading" : "Not at All",
"body" : "This is not the change I wanted. This is waste of four years and I amm waiting to see the promised change",
"email" : "kenshin#kay.com",
"createdAt" : ISODate("2016-05-13T21:12:58.977Z"),
"replies" : [ ],
"likes" : [ ]
}
],
"author" : "admin",
"image" : "/cfs/files/QuestionImages/DzdpK6NdurZMTwAse"
}
Hi all, I'm quite new to MeteorJs and I'm working on an app. i would like to know how to update the "likes" array. I want to push the currentUser's Id into the likes so on the front-end I will display yes.objectsReference.likes.length as the number of likes.
How can i target the likes array? thanks
You can use the $ positional operator on the server to update the likes array. Suppose you want to add the current user id to the likes array on the embedded "Yes" document with "heading" value "Well, Yes", then the following shows how you can do it on the server:
Articles.update(
{
"_id" : "s2QBCnv6fXv5YbjAP",
"yes.heading" : "Well, Yes"
},
{
"$push": { "yes.$.likes": userId }
}
)

Get all parent documents in a mongoDB model tree structure

I'm using a model tree structure for my collection. As references I'm using parent-fields. I need to get attributes from the current object and all its parents. The last element in a path has a field 'target'. So I start with
var result = parent = Articles.findOne({target: this.params._id});
do {
parent = Articles.findOne({_id: parent.parent}).parent;
for (var attrname in parent) { result[attrname] = parent[attrname]; }
}
while (parent.parent === null);
That seems to be very inefficient to me. Isn't it possible to do that with one line to get an object with all elements? Then I could process that object.
Example documents
{
"_id" : "LD6h5ZcDuJjexfKfx",
"title" : "title",
"publisher" : "public",
"author" : "author"
}
{
"_id" : "KSiyh8zHRq8RZQ2E6",
"edition" : "edition",
"year" : "2020",
"parent" : "LD6h5ZcDuJjexfKfx"
}
{
"_id" : "5yCk4y25wrLBLZhyY",
"pageNumbers" : "1-10",
"target" : "9sjhzPhyTuQ5Kbh6v",
"parent" : "KSiyh8zHRq8RZQ2E6"
}
So starting with "target" : "9sjhzPhyTuQ5Kbh6v" I would like to get the two parent documents (in this example).
At least I need the dataset
"title" : "title",
"publisher" : "public",
"author" : "author",
"edition" : "edition",
"year" : "2020",
"pageNumbers" : "1-10"
If you want to do this in a single query then you need to follow the array of ancestors pattern in Mongodb. Otherwise you need to recursively traverse the branches above the leaf node as you are doing. For hierarchies with low depth such as yours this is not a big penalty.
With an array of ancestors your doc tree would look like:
{
"_id" : "LD6h5ZcDuJjexfKfx",
"title" : "title",
"publisher" : "public",
"author" : "author",
}
{
"_id" : "KSiyh8zHRq8RZQ2E6",
"edition" : "edition",
"year" : "2020",
"ancestors" : ["LD6h5ZcDuJjexfKfx"],
"parent" : "LD6h5ZcDuJjexfKfx"
}
{
"_id" : "5yCk4y25wrLBLZhyY",
"pageNumbers" : "1-10",
"target" : "9sjhzPhyTuQ5Kbh6v",
"ancestors" : ["LD6h5ZcDuJjexfKfx","KSiyh8zHRq8RZQ2E6"],
"parent" : "KSiyh8zHRq8RZQ2E6"
}
To get the doc and its parents:
Articles.find({ $or: [ { target: target },
_id: { $in: Articles.findOne({ target: target }).ancestors }]});

Categories

Resources