Map object to string expression - javascript

The following fixed expression and values need to be changed to dynamic:
function update(args) {
const params = {
UpdateExpression: 'set firstName = :firstName, lastName = :lastName, sex = :sex',
// values map to UpdateExpression
ExpressionAttributeValues: {
':firstName': args.firstName,
':lastName': args.lastName,
':sex': args.sex
}
};
// db specific code, not relevant
}
It currently only works with fixed arguments, for example:
update({firstName: 'Joe', lastName: 'Doe', sex: 'M'}
I need the UpdateExpression and ExpressionAttributeValues to dynamically change with more or less arguments, e.g:
args also has height: 190
add height = :height to UpdateExpression (and comma)
add ':height': args.height to ExpressionAttributeValues
How should I parse that expression and how should I deal with the commas?
What I've got:
Expression string generation seems awkward and I have problems with commas.
const args = {
id: 'id-123',
firstName: 'John',
lastName: 'Doe',
updated: 1491111234
};
function update(args) {
console.log('===');
expression = 'set ';
values = {};
for (let variable in args) {
// expression string
let str = `${variable} = :${variable}, `;
console.log(str);
expression = expression.concat(str);
// values object
values[`:${variable}`] = args[variable];
}
console.log('---');
console.log('UpdateExpression:', expression);
console.log('ExpressionAttributeValues:', values);
console.log('===');
}
update(args);

You just need a way of determining when to add a comma, which should be every time except for the last. So you could use Object.keys to get the keys of the object and do a standard for loop to check if it's the last one.
const args = {
id: 'id-123',
firstName: 'John',
lastName: 'Doe',
updated: 1491111234
};
function update(args) {
console.log('===');
expression = 'set ';
values = {};
const keys = Object.keys(args);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = args[key];
const str = `${key} = :${key}`;
console.log(str);
expression += str;
values[`:${key}`] = value;
if (i < keys.length - 1) {
expression += ', ';
}
}
console.log('---');
console.log('UpdateExpression:', expression);
console.log('ExpressionAttributeValues:', values);
console.log('===');
}
update(args);

Related

How to return object of first and last names

The result is returning {firstname: 'Mike,Henry,Pete', lastname: 'Port,Split,Micky'}
I want result to return
{
firstName: Mike,
lastName: Port
},
{
firstName: Henry,
lastName: Split
},
{
firstName: Pete,
lastName: Micky
}
var data = "Mike Port, Henry Split, Pete Micky";
var firstName = [];
var lastName = [];
var result = [];
var newNames = data.replaceAll(", ", ",");
var fullName = newNames.split(',');
fullName.forEach(name => {
let splitted = name.split(" ");
firstName.push(splitted[0]);
lastName.push(splitted[1]);
});
f_name_list = firstName.toString().split(", ");
l_name_list = lastName.toString().split(", ");
for (let i = 0; i < f_name_list.length; i++) {
result.push({
firstname: f_name_list[i],
lastname: l_name_list[i]
});
}
console.log(result);
split data with ", " then split with " "
var data = "Mike Port, Henry Split, Pete Micky";
var result = [];
var newNames = data.split(", ");
newNames.forEach(name => {
let splitted = name.split(" ");
result.push({
firstname:splitted[0],
lastname: splitted[1]
});
});
console.log(result);
You can do in one line combining String#split() with Array#map() and Destructuring assignment
Code:
const data = 'Mike Port, Henry Split, Pete Micky'
const result = data
.split(', ')
.map(s => s.split(' '))
.map(([firstname, lastname]) => ({ firstname, lastname }))
console.log(result)
In the long-term it maybe better to not specify the keys in the code. What if you were to add a new property called age to the data? That would mean having to go into into the code and update it to accommodate the change which is a hassle.
This example removes that complication by keeping a track of the keys, and looping over them, and the values, to create a new dataset. No hard-coding of the keys anywhere.
const data = {
firstname: 'Mike,Henry,Pete',
lastname: 'Port,Split,Micky',
age: '10,100,20',
location: 'France,Germany,Iceland',
role: 'chef,musician,writer',
tree: 'larch,maple,oak'
};
// Get the keys and values from the object
const keys = Object.keys(data);
const values = Object.values(data).map(str => str.split(','));
// Temporary array
const out = [];
// Loop over the first array in the values array
for (let i = 0; i < values[0].length; i++) {
// Initialise an empty object
// for each nested array
const obj = {};
// Loop over the keys, create a new object with
// that key, and the element of the nested value array
// and merge it with the object
for (let j = 0; j < keys.length; j++) {
const prop = { [keys[j]]: values[j][i] };
Object.assign(obj, prop);
}
// Push the object to the array
out.push(obj);
}
console.log(out);
Additional documentation
Object.keys
Object.keys
Object.assign
Here is the code:
var data = "Mike Port, Henry Split, Pete Micky";
function parseData(data){
data = data.split(', ')
let arr = []
for(i=0;i<data.length;i++){
arr.push({firstName:data[i].split(' ')[0].replace(',',''),lastName:data[i].split(' ')[1]})
}
return arr
}
console.log(parseData(data))

How do I convert a string with a first name and last name to an object w/ properties of {firstName: "string first name", lastName: "string last name}?

function convertNameToObject(string) {
let obj = {};
obj.firstName = ;
obj.lastName = ;
return obj;
}
console.log(convertNameToObject("Harry Potter"));
Just split on the space character.
function convertNameToObject(string) {
const [firstName, lastName] = string.split(" ");
return { firstName, lastName };
}
console.log(convertNameToObject("Harry Potter"));
Little improved version that originally was provided by #Samathingamajig.
In the body of function there is IIFE expression.
function convertNameToObject(string) {
return (([firstName, lastName]) => ({firstName, lastName}))(string.split(" "))
}
console.log(convertNameToObject("Harry Potter"));

NodeJS loop through string and get the exact output

In NodeJS I have a string like this
"Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"
In the string you can see there are multiple Package, Qty and Price. Now I want to send email for each Qty and Package. So if you see Package Two it has Qty 3. So in that case there it will send 3 emails with Package and Price. So basically it will send email for each Qty with corresponding Package and Price.
So for now I have my code like this
var string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
var packArr = string.split('?');
var PackageName;
var PackagePrice;
for (var i = 0; i < packArr.length; i++) {
if( packArr[i].length > 0 ) {
let packageQty = packArr[i].split('&');
for (var j = 0; j < packageQty.length; j++) {
if( packageQty[j].match(/Package=/i) ) {
PackageName = packageQty[j].replace(/Package=/g,'');
console.log(PackageName);
}
if( packageQty[j].match(/Price=/i) ) {
PackagePrice = packageQty[j].replace(/Price=/g,'');
console.log(PackagePrice);
}
if (packageQty[j].match(/Qty=/i)) {
var ret = packageQty[j].replace(/Qty=/g,'');
var Pck = Number(ret);
for (var k = 1; k <= Pck; k++) {
console.log(k);
console.log('Package Name ' + PackageName);
console.log('Package Price ' + PackagePrice);
//send email with Package Name, Package Price
if( k == Pck ) {
break;
}
}
}
}
}
}
The above code actually not working properly. It is not getting the Package and Price properly for each loop. So can someone tell me how to do this in a easy way? Any help and suggestions will be really appreciable.
Here's a much cleaner way using querystring package
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
const qs = require('querystring');
// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);
// We loop through each group
for(const query of items) {
// Parse the query string of each group
const { Package, Qty, Price } = qs.parse(query);
for(let i = 0; i < Number(Qty); i++) {
// We send the email here <Qty> times.
console.log('Package Name ' + Package);
console.log('Package Price ' + Price);
}
}
I don't know how you feel about libraries, but Ramda (disclaimer: I'm one of the authors) is well-suited to data-transformations. And this screams for some straightforward data transformation.
I might use it to write a conversion function that changes your initial data into something like:
[
{Package: "Package", Price: 123, Qty: 1},
{Package: "Package Two", Price: 702, Qty: 3},
{Package: "Package Three", Price: 199, Qty: 1},
{Package: "Package One", Price: 852, Qty: 4}
]
This new format should then be easy to work with.
Here is a implementation that does this:
const {pipe, split, filter, map, fromPairs, evolve} = R;
const str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
const convertToObjects = pipe(
split('?'),
filter(Boolean),
map(split('&')),
map(map(split('='))),
map(fromPairs),
map(evolve({Price: Number, Qty: Number}))
);
console.log(convertToObjects(str))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
map, split, and filter should be obvious.
fromPairs turns [['a', 1], ['b', 2]] into {a: 1, b: 2}.
evolve takes a specification mapping property names to transformation functions, and transforms an object by applying those functions to the relevant properties, keeping all other properties intact. Here we use it with the JS Number function to convert {Package: 'Foo', Qty: '2', Price: '456'} into {Package: 'Foo', Qty: 2, Price: 456}.
and pipe creates a pipeline of functions in which the output of one function becomes the input to the next. Values supplied to the resulting function are sent to the first one and the result of the last one is returned.
Extending #Marcos-casagrande example here without external dependency using plain javascript
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);
// We loop through each group
items.map(query => {
// Parse the query string of each group
const {
Package,
Qty,
Price
} = query.split('&').reduce((acc, cur) => {
let arr = cur.split('=');
return {
...acc,
[arr[0]]: arr[1]
};
}, {});
for (let i = 0; i < Number(Qty); i++) {
// We send the email here <Qty> times.
console.log('Package Name ' + Package);
console.log('Package Price ' + Price);
}
})
Another way using only regexes and a few array methods, not requiring nested loops
var input = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"
var results = input
.split('?')
.map(s => /^Package=(.*?)&Qty=(.*?)&Price=(.*?)$/.exec(s))
.filter(s => s)
.map(s => ({
package: s[1],
qty: parseFloat(s[2]),
price: parseFloat(s[3])
}))
console.log(JSON.stringify(results, null, 4))
Here is a pure JS alternative, please take a look.
function extract(name, string) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(string);
return results == null ? null : results[1];
}
function parse(string) {
items = string.split('?');
results = [];
for (var i in items) {
if (items[i].length == 0) continue;
var item = '?' + items[i];
results.push({
package: extract("Package", item),
qty: extract("Qty", item),
price: extract("Price", item)
})
}
return results;
}
str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
document.getElementById('output').innerText = JSON.stringify(parse(str));
<div id='output'></div>

How to replace string {} value to obj (key value)

I recently started programming on nodeJs.
I have different strings and Json Object;
eg :
var str = 'My name is {name} and my age is {age}.';
var obj = {name : 'xyz' , age: 24};
var str = 'I live in {city} and my phone number is {number}.';
var obj = {city: 'abc' , number : '45672778282'};
How do I automate this process, so using string and obj I will replace string {} value to obj (key value).
I have tried PUG but not able to parse.
pug.render(str, obj);
Doesn't work for me.
lets see, you want to make something like templating, just like handlebars http://handlebarsjs.com/.
I will give you this example to make a simple-handlebars for you case:
function render(template, properties)
{
var result = template;
for (i in properties)
{
result = result.replace("{"+i+"}",properties[i]);
}
return result;
}
but this one will only change first occurence of respective properties, if you want you may use this for replace all in the whole template:
function render(template, properties)
{
var result = template;
for (i in properties)
{
var reg = new RegExp("{"+i+"}","g");
result = result.replace(reg,properties[i]);
}
return result;
}
Here is a variation on the theme.
var str = 'My name is {name} and {name} my age is {age}.';
var obj = {name : 'xyz' , age: 24};
var render = function (str, obj) {
return Object.keys(obj).reduce((p,c) => {
return p.split("{" + c + "}").join(obj[c])
}, str)
}
render(str, obj)
I think you should not re-invent the wheel because the easiest solution is to use some popular node modules.
I suggest 'sprintf-js'.
See my sample code here,
const sprintfJs = require('sprintf-js')
const template = 'hello %(name)s today is %(day)s'
const data = {
name: 'xxxx',
day: 'Tuesday'
}
const formattedString = sprintfJs.sprintf(template, data)
console.log(formattedString)
This is possible with single replace call.
var obj = {name : 'xyz' , age: 24};
let c_obj = {};
let wordArr = [];
const res = str.matchAll("{.*?}");
for(const match of res){
c_obj[match[0]] = obj[match[0].slice(1,-1)];
wordArr.push(match[0]);
}
let new_str = str.replace(new RegExp(wordArr.join('|'),'g'), match => c_obj[match]);

how to split function in javascript

i have data in
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
i want the result as
Name: John
Employee Id: 2
Salary: $8000
Address: London
is it possible with split() function in javascript?
You can do it with String.split() but in this case it's simpler to use String.replace():
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
description = description.replace(/;/g, '\n').replace(/:/g, ': ');
/*
"Name: John
EmployeeID: 2
Salary: $8000
Address: London"
*/
If you want the result as an object, try:
var f = function (str) {
var x = {}, key2label = { EmployeeID: 'Employee Id' };
str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value) {
key = key2label[key] || key;
x[key] = value;
});
return x;
};
If a simple string is needed, but you still need to replace keys:
var f2 = function (str) {
var key2label = { EmployeeID: 'Employee Id' };
return str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value, semi) {
key = key2label[key] || key;
return key + ': ' + value + (semi ? '\n' : '');
});
};
If you really didn't mean to replace keys, this will do it:
var f3 = function (str) {
return str.split(':').join(': ').split(';').join('\n');
};
... or use Matt Ball's answer.
With this statement:
var arrDescription = description.split(";");
you will get an array with all the values. For more info on split check the following link.
you can even join them afterwards :
printf(arrDescription.join(" "));
For more info on join check the following link.
Max
You can probable try like this to display.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
var arr=new Array();
arr=description.split(";");
for(var i=0;i<arr.length;i++)
document.writeln("<h4>"+arr[i]+"</h4>");
Yes.
You first should split on the semicolon ;. Loop through those results, and split each result on each colon :.
You will have to build the result by hand.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London"; var splitted = description.split(";");
for(var i = 0; i < splitted.length; i++) { document.write(splitted[i] + ""); }

Categories