Parse JSON-like string into object using JavaScript - javascript

I have a problem about using JSON-like string parser: sometimes users will not input a correct strict JSON string. For example:
input =
"name: John,
age: 20,
products: [
{ id : 100, name: flower },
{ id : 101, name: snack },
],
home: New York,
education: {
highSchool: {
name: Stuyvesant High School,
GPA: 3.2
},
college: {
name: Fordham University,
GPA: 2.8
}
}"
The input above is not able to parse using JSON.parse() because both key and value does not fit contained by "" (name: John instead of "name": "John")
How can we get the expected output like this:
console.log(customParser(input));
//expected
/*
name: "John",
age: 20,
products: (2) [{...}, {...}]
home: "New York"
education: (2) {highSchool: {...}, college: {...}}
*/

As an alternative to writing your own parser from scratch, you might consider interpreting the user input as YAML. For example, the Node.js command require("js-yaml").load(input) converts your example input into the following Javascript object:
{
name: 'John,',
age: '20,',
products: [ { id: 100, name: 'flower' }, { id: 101, name: 'snack' } ],
home: 'New York,',
education: {
highSchool: { name: 'Stuyvesant High School', GPA: 3.2 },
college: { name: 'Fordham University', GPA: 2.8 }
}
}
Except for the trailing commas at the end of the string-valued properties, that is what you want. Either educate your users to leave these commas out, or write a pre-processor that removes them before calling the .load function of js-yaml.

Related

DynamoDB, BatchWriteItem for an array - AWS V3

I have an array I am using to create a put for batchwriteitem.
const people = [{
location: 'London',
name: 'Tony Wilson',
pets: [ {name: 'Cuddles', age: 4}, { name: 'Jess', age: 2}]
},
{
location: 'Manchester',
name: 'Liz Smith',
pets: [ {name: 'Fluffy', age: 4}, { name: 'Keith the cat', age: 2}]
}
]
My batchwriteitem loop is working for individual items
location: { S : item.location },
but when I try and input the pets array as an array it fails
pets: { M: item.pets },
So this all works except the pets array.
const request = pets.map(item => {
const createdDate = Date.now();
return {
PutRequest: {
Item: {
location: { S : item.location },
createdDate:{ N: createdDate },
pets: { M: item.pets }
}
}
});
Do I need to break down the pets array into types and if so how can I achieve this?
Edit
pets: { L: item.pets }, does not work
**Cannot read properties of undefined (reading '0')
and the old syntax without the types does not work on v3 with the document client for me.
Pets is an array, which is also known as a list type. You are setting it as a dictionary/map type as you've set the value to M. It should be L:
pets: { L: item.pets },
I would advise that you use the Document Client as it means you do not need to think about the type conversions, and just use native JSON objects:
pets: item.pets,

Find All Records Between a Range of Two Numbers in a MongoDB Query

Is there a way in MongoDB to get records between a range of numbers?
In my example, I am finding the records that match common: 1, and am using a fake range() function to get only the records between that range. In theory, you could just put any numbers in the range function and it would output the records in that range.
This is not what I am asking: $gte, $gt, $lte, $lt
Note: I am not querying based on values. I am querying based on the records natural position in the filesystem relative to all other records.
Users Collection:
db.users = [{
_id: 123,
name: "Bill",
common: 4
},
{
_id: 456,
name: "Jeff",
common: 2
},
{
_id: 789,
name: "Steve",
common: 4
},
{
_id: 321,
name: "Elon",
common: 3
},
{
_id: 654,
name: "Larry",
common: 1
},
]
Unworking Example: (range() isn't a real function, just used to give an idea)
users.find({common: 4}).range(0, 2).then((users) => {
console.log(users)
})
Expected Result: (because the common fields match and the records are between the range 0 and 2)
db.users = [{
_id: 123,
name: "Bill",
common: 4
},
{
_id: 789,
name: "Steve",
common: 4
},
]
This doesn't give the exact expected result, but the whole idea was to select records between two numbers (eg. a range). The way you do this is with the $skip and $limit methods.
users.aggregate([{$skip: 1}, {$limit: 3}, {$match: {common: 4}} ]).then((users) => {
console.log(users)
})

how to search an object inside an array of objects in mongoose?

i have my structure like this :
test{
_id: 60eadb64b72caa2ae419e085,
testid: 'hh',
time: 45,
testPassword: 123,
startTime: 2021-07-11T11:52:04.245Z,
Students: [
{
_id: 60eadb98b72caa2ae419e088,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'dsc',
firstName: 'ccccc',
group: 2,
time: 0.8772833333333333
},
{
_id: 60eadbb5b72caa2ae419e08c,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'eqf',
firstName: 'aaaaa',
group: 56,
time: 1.357
}
],
__v: 0
}
i want to get just the object that has the _id: 60eadb98b72caa2ae419e088 from the array of students like this
{
_id: 60eadb98b72caa2ae419e088,
submission: '#*#org 0h #*##*#ret#*#',
familyName: 'dsc',
firstName: 'ccccc',
group: 2,
time: 0.8772833333333333
}
you can search inside array of objects in mongoose like this
db.collection.find({"Students._id": yourId})
you can go as deep as you want
db.collection.find({"Students.users.info.name": username})
and for a single match you can use findOne like this
db.collection.findOne({"Students._id": yourId})
the if you want only the object inside the Students array you can find it by javascript find function
const wantedObject = myObj.Students.find(e => e._id === "60eadb98b72caa2ae419e088")
You can use following aggregate to find you required result, I have tried at my local it is working fine
db.users.aggregate([
{
$match:{
"Students._id":ObjectId("60eadb98b72caa2ae419e088")
}
},{
$unwind:"$Students"
},
{
$project: {
submission:"$Students.submission",
_id:"$Students._id",
familyName:"$Students.familyName",
firstName:"$Students.firstName",
group:"$Students.group",
time:"$Students.time",
}
},
{
$match:{
_id:ObjectId("60eadb98b72caa2ae419e088")
}
}
]);

Convert array of objects to another array of objects

I need to convert array of objects to just objects to use it in table datasource:
{v_report_full: Array(25)}
v_report_full: Array(25)
0:
first_name: "Blake"
last_name: "Thorphan"
middle_name: "Agder"
monh: "2021-02-01 00:00:00"
n_vh: "Delay 00:04:52"
n_vh_s_obeda: "ok"
n_vyh: "ok"
n_vyh_s_obeda: "ok"
name: "oitib"
rtime: null
vh_s_obeda_ts: null
vhod_ts: "2021-02-01 08:59:52"
vyh_s_obeda_ts: null
vyhod_ts: null
__typename: "Ereport"
__proto__: Object
1:.. the same next index
2:.. the same next index
Table datasource requires next order:
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
I've tried to use Object.keys, but have not enough expirience to do that. If here is a simple solution, if not I have to write a loop for each row with function to concat, etc?
Upd. These one was I worked with:
let dataSource = (data) ? data.v_report_full.map((value, index, array) => {
return {
id: value.id,
key: value.id,
first_name:(value, 'first_name'),
.....
}
After hatfield advise, I checked once more and it's working! A liitle changes and above code then working now D: What a noob I am.

Lodash sortByOrder with provided alphabet

I need to sort an array of objects by provided keys. Sorting must be case-insensitive and use provided alphabet. For example let's take initial data that looks like this:
var notOrdered = [{
date: "11-12-2015",
name: "Tomasz",
age: 50,
products: "FDGS",
rate: 500
}, {
date: "12-11-2015",
name: "Łukasz",
age: 54,
products: "ŁBDGS",
rate: 110
}, {
date: "11-12-2015",
name: "Jan",
age: 24,
products: "ŻDGS",
rate: 1000
}, {
date: "11-12-2015",
name: "Łucja",
age: 18,
products: "AEBDGS",
rate: 50
}];
var keys = ["date", "rate", "name"];
var directions = [true, false, true];
var alphabet = '01234567989aąbcćdeęfghijklłmnńoóprsśtuvwxyzźż'
So the result I'm looking for is:
var ordered = [{
date: "11-12-2015",
name: "Łucja",
age: 18,
products: "AEBDGS",
rate: 50
}, {
date: "11-12-2015",
name: "Jan",
age: 24,
products: "ŻDGS",
rate: 50
}, {
date: "11-12-2015",
name: "Tomasz",
age: 50,
products: "FDGS",
rate: 500
}, {
date: "12-11-2015",
name: "Łukasz",
age: 54,
products: "ŁBDGS",
rate: 110
}];
Using lodash's sortByOrder function var ordered = _.sortByOrder(notOrdered, keys, directions) takes care of sorting using provided keys and directions - one after another. And it works great. What I need now is to use provided alphabet order instead of the default one and make comparisons case-insensitive.
All the chars that are not listed in the provided alphabet should be compared the default way. I cannot use localCompare, because I need to support old IE and mobile browsers.
The question is: can I somehow make lodash's sortByOrder function to use custom alphabet and if so, how to do it?

Categories

Resources