I Need help regarding an SQL result to be converted into an array of objects.
SQL returns results with these columns in JSON format:
po_no
po_line_no
material_no
material_name
po_qty
grpo_qty
These should be nested into:
po_no,
lines: {
po_line_no,
material_no,
material_name,
po_qty,
items: {
grpo_qty
}
}
However, I don't know how to nest 3 or more levels deep using ES6.
I was using this code before,
Object.values(data.reduce((r, {column1,column2, column3, column4}) => {
r[column1] = r[column1] || {column1, column2_items}
r[column1].column2_items.push({ column2: column2 })
}))
But I don't know how to nest it deeper.
Related
I have 2 different JSON responses from 2 different GET methods from postman.
I am trying to write a test to compare them.
the first response is specificYield
[
[
"2020-11-30T00:00:00Z",
50.701604514154944
],
[
"2020-12-31T00:00:00Z",
19.328539610238128
],
[
"2021-01-31T00:00:00Z",
25.183636870929693
]
]
The second response is expectedYield
[
[
"2020-11-30T00:00:00Z",
62.78336503569246
],
[
"2020-12-31T00:00:00Z",
32.97678871921154
],
[
"2021-01-31T00:00:00Z",
40.82916109964013
]
]
I am trying to check that the integer value in the expectedYield array is always greater than the value in the specificYield array
so it will compare the 62.78336503569246 to 50.701604514154944
and then 32.97678871921154 to 19.328539610238128
and so on
The test looks like this so far, but I know im not using objects anymore and am trying to refactor it to just work with arrays.
pm.test("Expected Yield > Specified Yield", function () {
const expectedYield = pm.response.json();
const specificYield = pm.globals.get("specificYield");
Object.values(expectedYield).forEach((record) => {
pm.expect(record[0][1]).to.greaterThan(
Object.values(specificYield).forEach((record) => {
pm.expect(record[0][1]);
})
);
});
});
I don't know PostMan syntax, but the standard JS syntax would be
expectedYield.every((record, i) => record[1] > specificYield[i][1])
The second argument i to the callback function is the index of the element being tested. This is used to compare that record with the corresponding record of the other array.
Then we use every() to check that it's true for the entire array. There's no need to use Object.values() -- that's used to convert the properties of an ordinary object to an array in order to use array methods, but these are already arrays.
So I have this array of strings which I'm using as filter to fetch documents from MongoDB using Mongoose. I'm successfully getting the data back from the db, but it is also returning Promise { <pending> } on the console even though I'm wrapping the map function with Promise.all.
Please note that this map function is nested inside two level deep for in loops which I'm leaving out for simplicities sake.
Suppose this is the array of strings:
const subCategories = [ 'Politics', 'Entertainment' ];
And this is the map function:
const subCategoryID = await Promise.all( subCategories.map( async item => {
try {
const data = await SubCategory.findOne( { subCategory: item } );
return data;
} catch( e ) {
throw err;
}
}));
console.log( subCategoryID );
Promises make my head spin. I have tried learning Promises more than 5-6 times in the last 1-2 years and it still confuses me. So if you can, please provide a solution with Async/Await.
If you only want the result, Try this approach:
const subCategories = [ 'Politics', 'Entertainment' ];
const queries = subCategories.map((i) => {
return { subCategory: i };
});
const subCategoryID = await SubCategory.find({
$or: queries,
});
console.log(subCategoryID);
using $or operator is explained in mongodb manual:
The $or operator performs a logical OR operation on an array of two or more <expressions> and selects the documents that satisfy at least one of the <expressions>.
more about it here.
In mongoose, you can use it in any find methods.
for explanation about your promise, sorry I can't help.
Please mark answered if this solves your problem.
I am receiving a json response from an API call. I need to store its keys, and create an array of an object. I am intending to this array of an object is created dynamically no matter the keys of the response.
I've already got the keys like this:
const json_getAllKeys = data => {
const keys = data.reduce((keys, obj) => (
keys.concat(Object.keys(obj).filter(key => (
keys.indexOf(key) === -1))
)
), [])
return keys
}
That returned an array (using a sample json):
['name','username', 'email']
But I am trying to use that array to create an array of object that looks like this one
[
{
name: "name",
username: "username",
email: "Email",
}
];
I've been trying mapping the array, but got multiple objects because of the loop, and I need a single one to make it work.
keys.map(i=>({i:i}))
[
{ i: 'id' },
{ i: 'name' },
{ i: 'username' },
{ i: 'email' }
]
Any hint would be useful!
Thanks in advance :D
What you're looking for is Object.fromEntries, which is ECMA2019, I believe, so available in Node >=14 and will be provided as a polyfill if you employ babel.
I can't quite discern what your reduce should produce, but given the sample input, I would write
const input = ['name','username', 'email'];
const result = Object.fromEntries(input.map(name => ([name, name])));
// result == { name: 'name', username: 'username', email: 'email' }
You're definitely on the right track. One thing to remember is the map function will return the SAME number of output as input. So in your example, an array of 3 returns an array of 3 items.
For this reason, map alone is not going to give you what you want. You may be able to map => reduce it. However, here is a way using forEach instead. This isn't a strictly functional programming style solution, but is pretty straight forward and depending on use case, probably good enough.
let keys = ['name','username', 'email'] //you have this array
const obj = {}; // empty object to hold result
keys.forEach(i => {
obj[i] = i; // set the object as you want
})
console.log(obj); // log out the mutated object
// { name: 'name', username: 'username', email: 'email' }
I have an array with nested array
I want the data to append in a new array.
For the data extraction or filtration what method's i have to use, using library such as lodash
DATA
[
[
{
_id: 588d9b8a608f2a66c298849f,
email: 'sd#',
password: '$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC',
isJobSeeker: true,
__v: 0,
lastName: 'shrestha',
firstName: 'manish',
isSeeker: true
}
],
[
{
_id: 588dbb4f7a48ce0d26cb99fd,
jobId: [Object],
seekerId: 588d9b8a608f2a66c298849f,
employerId: 588d7d6c0ec4512feb819825,
__v: 0,
}
]
]
REQUIRED DATA
[
{
_id: 588d9b8a608f2a66c298849f,
email: 'sd#',
password: '$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC',
isJobSeeker: true,
__v: 0,
lastName: 'shrestha',
firstName: 'manish',
isSeeker: true
},
jobId: [{}, {}, {}] // ARRAY WITH OBJECTS
]
also i want to change the jobId key to other key of custom string as jobs
Following is my attempt:
console.log('Data filteration', data);
const filteredData = [];
filteredData.push(data[0][0]);
data[1].forEach((i) => {
filteredData[0].jobs = i.jobId
});
console.log('filteredData', filteredData);
First you should clean you data to have a better structure.
[
[
{ ... }
],
[
{ ... }
]
]
In this datastructure, its difficult to understand what does inner arrays signify. Instead you should use an object. That would define the purpose of array and make your code more readable.
var data=[[{_id:"588d9b8a608f2a66c298849f",email:"sd#",password:"$2a$10$6..L3c3tANi6ydt9gZbc1O6prPfUd3RB.ner5lilxRyEwo1lPsSoC",isJobSeeker:!0,__v:0,lastName:"shrestha",firstName:"manish",isSeeker:!0}],[{_id:"588dbb4f7a48ce0d26cb99fd",jobId:["test","test1"],seekerId:"588d9b8a608f2a66c298849f",employerId:"588d7d6c0ec4512feb819825",__v:0}]];
var cleanedData = {
userData: data[0],
userJobMap: data[1],
}
var result = cleanedData.userData.reduce(function(p,c){
if(c.isJobSeeker){
var job = cleanedData.userJobMap.filter(x=> x.seekerId === c._id);
// To copy object and not reference
var t = Object.assign({}, c, { jobId: job[0].jobId });
p.push(t)
}
return p
}, [])
console.log(result)
References
Array.map is a tool that iterates over all elements and return different value say a single property of return double value of all numbers in array. Note, this will yield an array of same size.
Array.filter on the other hand is use to filter array based on condition. This will return a subset of original data but elements will be same. You cannot change element structure.
Array.reduce is a tool that address cases where you need to return selected elements with parsed value. You can achieve same by chaining .filter().map() but then its an overkill as it would result in O(2n).
Object.assign In JS objects are passed by reference. So if you assign an object to a variable, you are not copying entire object, but only reference. So it you change anything in this variable, it will also reflect in original object. To avoid this, you need to copy value. This is where Object.assign comes. Note, its not supported by old browsers. For them you can check following post - What is the most efficient way to deep clone an object in JavaScript?
Note: All array functions are part of functional programming paradigm and are used to make your code more readable and concise but they come at an expense of performance. Traditional for will always perform faster then them. So if you want to focus on performance, always try to use for (though difference is very small but can add up for multiple cases and become substantial)
I'm new to MongoDB, and trying to reorder an array in a db.
Here's the schema:
headline: String,
Galleryslides: [{type: ObjectId, ref: 'Galleryslide'}],
Here's the logic I'm using. By the way, correctOrder is an array with the new order of ids for the DB.
Gallery.findById(req.params.galleryId, function(err, gallery) {
var newArr = [];
req.body.ids.forEach(function(id, index) {
newArr[index] = Galleryslides.find({"_id" : id});
});
gallery.Galleryslides = newArr;
gallery.save(function() {
res.json({status: 'ok'});
});
});
When this runs, nothing happens - the order of the array in the DB does not change. D'you know a better way to do this?
In mongodb, the records are sorted in natural order. You should get them in the same order you inserted but that's not guaranteed.
Like the docs say :
This ordering is an internal implementation feature, and you should
not rely on any particular structure within it.
If you want to sort by the _id field, you can do that(it will sort by the _id index) :
Gallery.find().sort({ "_id": 1 })