Wildcard Search in a collection with lodash - javascript

I've an array like the one shown below and I want to do a wildcard search and retrieve the corresponding value. This is not returning me any result, can someone help me if there is any better way to do this. I'm using lodash utilities in my nodejs application.
var allmCar = [
{
"_id": ObjectId("5833527e25bf78ac0f4ca30e"),
"type": "mCar",
"value": "ABDC",
"__v": 0
},
{
"_id": ObjectId("5833527e25bf78ac0f4ca30e"),
"type": "mCar",
"value": "XYZ ABD",
"__v": 0
},
{
"_id": ObjectId("5833527e25bf78ac0f4ca30e"),
"type": "mCar",
"value": "FGHJ",
"__v": 0
}
]
_.find(allmCar, {
value: {
$regex: 'XYZ'
}
})
I finally ended up using _.includes as below
_.each(allmCar,function(car){
if(_.includes('XYZ', car.value)===true)
return car;
})

You can do the same with a function passed to _.find, like this
_.find(allmCar, function(mCar) {
return /XYZ/.test(mCar.value);
});
Or with arrow functions,
_.find(allmCar, (mCar) => /XYZ/.test(mCar.value));
This will apply the function passed to all the items of the collection and if an item returns true, that item will be returned.

Related

Iterate through array of objects using javascript

I am trying to iterate through the array of objects but somehow not getting it right. Can somone please let me know where i am going wrong.
Here is the data
const response = {
"pass": 1,
"fail": 2,
"projects_all": [
{
"projects": [
{
"name": "Project1",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
},
{
"projects": [
{
"name": "Project2",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "FAIL",
}
},
{
"name": "Project3",
"status": "LIVE",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
}
]
}
And here is the code i tried
if(response) {
response?.projects_all?.forEach((projects) => {
projects.forEach(project) => {
if(project.previous !== null) {
//do something here
}
});
});
}
I am trying to iterate through this array of objects but it says projects not iterable. Any help is appreciated to make me understand where i am going wrong.
You were missing iterating over an array properly. A good idea is to format the JSON object that you plan to iterate over. So that you can see what are the arrays and objects, and at what hierarchy.
if (response) {
response?.projects_all?.forEach((project) => {
project?.projects?.forEach((project) => {
console.log(project?.name);
});
}
);
}
response?.projects_all?.forEach((projects) => {
This is the exact correct way to start the code. The problem that happens next is you apparently misunderstand what projects means in the following context
You do projects.forEach(project) as if you think projects is as array. projects is not an array at this point, it is an object that looks like this:
{
"projects": [
{
"name": "Project1",
"current": null,
"previous": {
"environment": "qa4nc",
"status": "UNKNOWN",
}
}
]
}
So I would actually want to do projects.projects.forEach(project => { ... }), or you could change the variable name from projects so it makes more sense to read.
First, determine what shape your response object currently has.
By using the ?. operator your essentially muting JS built in error reporting.
From the context, I assume your response actually looks like this:
console.log(response);
{
data: {
projects_all: [ ... ]
}
}
Therefore your existing code using response?.projects_all doesn't actually hit the projects_all property inside your response.
Can you try the following:
response.data.projects_all.forEach((project) => {
console.info("Project: ", project);
project.projects.forEach((project) => {
console.log(project, project?.name);
});
});
Alternatively, if you don't have a data key inside your response object, you can omit it in the loop:
response.data.projects_all.forEach((project) => {
console.info("Project: ", project);
project.projects.forEach((project) => {
console.log(project, project?.name);
});
});

Taking contents of an array of objects, and assigning them to a property on a JSON object

I want to take items from this array (the way I save things on the client)
[
{
"id": "-Mdawqllf_-BaW63gMMM",
"text": "Finish the backend[1]",
"status": true,
"time": 1625248047800
},
{
"id": "-Mdawqllf_-BaW63gGHf",
"text": "Finish the middle-end[2]",
"status": false,
"time": 1625248040000
},
{
"id": "-Mdawqllf_-BaW63gGHd",
"text": "Finish the front-end[3]",
"status": false,
"time": 1625248040000
}
]
And turn them into this format for how I save it server side
{ "todos": {
"-Mdawqllf_-BaW63gMMM": {
"text": "Finish the backend[1]",
"status": true,
"time": 1625248047800,
},
"-Mdawqllf_-BaW63gGHf": {
"text": "Finish the middle-end[2]",
"status": false,
"time": 1625248040000,
},
"-Mdawqllf_-BaW63gGHd": {
"text": "Finish the front-end[3]",
"status": false,
"time": 1625248040000,
}
},
}
Basically i turn items into an array on the client to help with sorting and making use of arrays. But before sending it back need to put into the right format
Use .map() to loop over the array of objects to exctract the id property, so you can use it as the key of the new object.
Use Object.fromEntries() to create the new object from the array returned by .map().
const data = [
{
"id": "-Mdawqllf_-BaW63gMMM",
"text": "Finish the backend[1]",
"status": true,
"time": 1625248047800
},
{
"id": "-Mdawqllf_-BaW63gGHf",
"text": "Finish the middle-end[2]",
"status": false,
"time": 1625248040000
},
{
"id": "-Mdawqllf_-BaW63gGHd",
"text": "Finish the front-end[3]",
"status": false,
"time": 1625248040000
}
];
const todos = {
Todos: Object.fromEntries(data.map(obj => [obj.id, obj]))
};
console.log(todos);
#Barmar's solutions is nice.
For the sake of learning or others googling. You can also reduce the array to an object.
const todos = data.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {})
const items = {
todos: {
...data
}
};
Assume that data is the array of objects.
Use the spread operator to copy all the array objects from data array to the todos object at key todos.
One important thing to note that you can't assign more than one objects without array to a single object key. You definately have to use the array to maintain all the objects under the one key.
Avoid using the hardcode index. Always use the spread operator

Loop into Array of Objects comparing two arrays - PUG (Jade)

I am trying in Javascript, using PUG template (if possible), to compare two arrays and when I find a correspondance in IDs, display some particular elements.
// First Array : I iterate over "hearts" object
// Called in PUG : - const user
[
{
"hearts": [
"5e70c63a94b27b164c9b897f",
"5e723c75e4bfdf4f58c55e32"
],
"_id": "5e6bb1189978fd5afc98c57a",
"email": "catherine#catherine.com",
"name": "Catherine",
"photo": "0121b7fe-b2ae-4e75-979d-7dea1a432855.jpeg",
"__v": 0
},
{
"hearts": [
"5e723c75e4bfdf4f58c55e32"
],
"_id": "5e6bc41f5915e3d2980a5174",
"email": "marc#marc.com",
"name": "Marc",
"photo": "4caa7bfb-6408-4893-a78b-fa6e8e5b03e7.png",
"__v": 0
}
]
// Second array : I iterate over "author.hearts" object
// Called in PUG : - const store
[{
"product": {
"categories": [
1,
2
]
},
"_id": "5e6bcc76c4022eae00e22af6",
"date": "2222-02-20T21:22:00.000Z",
"author": {
"hearts": [
"5e723c75e4bfdf4f58c55e32",
"5e70c63a94b27b164c9b897f"
],
"_id": "5e6bb1189978fd5afc98c57a",
"__v": 0
},
"created": "2020-03-13T18:09:58.086Z",
"id": "5e6bcc76c4022eae00e22af6"
}]
I want to loop over the first array, find the first ID (here 5e70c63a94b27b164c9b897f), loop over the second array and see if this ID is present within the "author.hearts" object. If it is not, carry on with the second ID and if it is present, display all the keys (tags, photos, _id, date...) from the object where the ID was found.
In my example, I have just one object in my array, but I'll be having much more later on.
Many thanks for your help
If I'm understanding correctly you can do something like this. Loop through all your users and when you find their id in author.hearts stop the loop there and return the object the user's _id was found in.
var resultFound = undefined;
try {
user.forEach((el) => {
const id = el._id;
const result = store.find(el => el.author.hearts.includes(id));
if (result) {
resultFound = result;
throw resultFound;
}
});
} catch (e) {
if (e !== resultFound) {
throw e;
}
}

Query Comparing Arrays of Objects

I'm wondering how I can compare arrays of (nested) objects in Mongoose.
Considering the data below, I would like to get results when the name properties match. Could anyone help me with this?
Organisation.find( {
$or: [
{ "category_list": { $in: cat_list } },
{ "place_topics.data": { $in: place_tops } }
]
}
)
Let's say that this is the data stored in my MongoDB:
"category_list": [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
],
"place_topics": {
"data": [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
}
And let's say that these are the arrays I want to compare against (almost the same data):
let cat_list = [
{
"id": "197750126917541",
"name": "Pool & Billiard Hall"
},
{
"id": "197871390225897",
"name": "Cafe"
},
{
"id": "218693881483234",
"name": "Pub"
}
]
let place_tops = [
{
"name": "Pool & Billiard Hall",
"id": "197750126917541"
},
{
"name": "Pub",
"id": "218693881483234"
}
]
When there are "multiple conditions" required for each array element is when you actually use $elemMatch, and in fact "need to" otherwise you don't match the correct element.
So to apply multiple conditions, you would rather make an array of conditions for $or instead of shortcuts with $in:
Organizations.find({
"$or": [].concat(
cat_list.map( c => ({ "category_list": { "$elemMatch": c } }) ),
place_tops.map( p => ({ "place_topics": { "$elemMatch": p } }) )
)
})
However, if you take a step back and think logically about it, you actually named one of the properties "id". This would generally imply in all good practice that the value is in fact ""unique".
Therefore, all you really should need to do is simply extract those values and stick with the original query form:
Organizations.find({
"$or": [
{ "category_list.id": { "$in": cat_list.map(c => c.id) } },
{ "place_topics.id": { "$in": place_tops.map(p => p.id) } }
]
})
So simply mapping both the values and the property to "match" onto the "id" value instead. This is a simple "dot notation" form that generally suffices when you have one condition per array element to test/match.
That is generally the most logical approach given the data, and you should apply which one of these actually suits the data conditions you need. For "multiple" use $elemMatch. But if you don't need multiple because there is a singular match, then simply do the singular match

elasticsearch autosuggest returning tricky JSON

I'm running a node.js server that sends queries to an elasticsearch instance. Here is an example of the JSON returned by the query:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 9290,
"max_score": 0,
"hits": []
},
"suggest": {
"postSuggest": [
{
"text": "a",
"offset": 0,
"length": 1,
"options": [
{
"text": "Academic Librarian",
"score": 2
},
{
"text": "Able Seamen",
"score": 1
},
{
"text": "Academic Dean",
"score": 1
},
{
"text": "Academic Deans-Registrar",
"score": 1
},
{
"text": "Accessory Designer",
"score": 1
}
]
}
]
}
}
I need to create an array containing each job title as a string. I've run into this weird behavior that I can't figure out. Whenever I try to pull values out of the JSON, I can't go below options or everything comes back as undefined.
For example:
arr.push(results.suggest.postSuggest) will push just what you'd expect: all the stuff inside postSuggest.
arr.push(results.suggest.postSuggest.options) will come up as undefined even though I can see it when I run it without .options. This is also true for anything below .options.
I think it may be because .options is some sort of built-in function that acts on variables, so instead of seeing options as JSON and is instead trying to run a function on results.suggest.postSuggest
arr.push(results.suggest.postSuggest.options)
postSuggest is an array of object.options inside postSuggest is also array of object. So first you need to get postSuggest by postSuggest[0] and then
postSuggest[0].options to get array of options
This below snippet can be usefule
var myObj = {..}
// used jquery just to demonstrate postSuggest is an Array
console.log($.isArray(myObj.suggest.postSuggest)) //return true
var getPostSuggest =myObj.suggest.postSuggest //Array of object
var getOptions = getPostSuggest[0].options; // 0 since it contain only one element
console.log(getOptions.length) ; // 5 , contain 5 objects
getOptions.forEach(function(item){
document.write("<pre>Score is "+ item.score + " Text</pre>")
})
Jsfiddle

Categories

Resources