how to search string in whole string in loopback query - javascript

I want search whole string when I type any word, it's matched only first Character not matched whole string and middle character of string.
query.and.push({ or: [{ name: { like: '^' + data.searchTextNEM + '.*', options: 'i' } }, { email: { like: '^' + data.searchTextNEM + '.*', options: 'i' } },{ phone: { like: '^' + data.searchTextNEM + '.*', options: 'i' } }]});
Users.find({where: query, limit: data.limit,skip: data.skip },function(err,res){})
Like I have two string 1.mark and 2.denim if I type 'm' my response should be mark and denim but getting response only mark

You may have try this:-
name: { ilike: '%' + data.searchTextNEM + '%' }
It will also match with case insensitive text.
or:
you may have pass the options in like filter:-
?filter={"where":{"title":{"like":"someth.*","options":"i"}}}

I think your regex is incorrect. If you insert 'm' your regex becomes ^m.* which means "starts with m and then has any number of any characters". I think you want .*m.* which means "has any number of any character, then an m, then any number of any character":
query.and.push({ or: [{ name: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } }, { email: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } },{ phone: { like: '.*' + data.searchTextNEM + '.*', options: 'i' } }]});
Users.find({where: query, limit: data.limit,skip: data.skip },function(err,res){
})

Related

remove extra spaces in string in javascript

I have a text and after deleting special characters (!##$%^&*()-=+`";:'><.?/) and show just letters and numbers (and float numbers like 23.4 ) it returns some extra space
const input : 'this is a signal , entry : 24.30 and side is short';
const text = input.replace(/\.(?!\d)|[^\w.]/g, " ").toUpperCase();
console.log(text.split(" "))
the output :
[
'THIS', 'IS', 'A',
'SIGNAL', '', '',
'', 'ENTRY', '',
'', '24.30', 'AND',
'SIDE', 'IS', 'SHORT'
]
but I want to be this :
[
'THIS', 'IS', 'A',
'SIGNAL', 'ENTRY', '24.30',
'AND', 'SIDE', 'IS',
'SHORT'
]
And when I replace spaces and enters with empty string , returns this :
[ 'THISISASIGNALENTRY24.30ANDSIDEISSHORT' ]
what is the problem of my code?
Instead of replacing, consider matching all the sorts of characters you want to produce the array of words. It looks like you want something like:
const input = 'this is a signal , entry : 24.30 and side is short';
const matches = input.toUpperCase().match(/[\w.]+/g);
console.log(matches);
The second parameter in the replace method needs to be an empty string and not a space as you have it in your code.
Just do:
...
const text = input.replace(/\.(?!\d)|[^\w.]/g, "").toUpperCase();
...

Leaderboard from database using MongoDB/Mongoose

In each document there is a level field with a Number value and a twitch_username with a String value. I want to return these values like so:
1. Twitch: <twitch_username> Level: <level>
2. Twitch: <twitch_username> Level: <level>
3. Twitch: <twitch_username> Level: <level>
//...
I tried mapping through the data, running a for loop, pushing the data into a new array, etc. but can't seem to wrap my head around it.
Currently running this query which returns the specific data I need in descending order:
User.find({}).select('twitch_username level -_id').sort({level: 'desc'}).exec((err,docs) => {
// console.log(docs);
});
The query above returns:
[
{ twitch_username: 'user1', level: 67 },
{ twitch_username: 'user2', level: 14 }
]
Which is sort of what I want but I can't individually label each value, the data is returned but I can't do anything with it.
You can use array reduce to reduce it to a string
const output = [
{ twitch_username: 'user1', level: 67 },
{ twitch_username: 'user2', level: 14 }
];
Then use reduce function
output.reduce((final, current, id) => {
return (final + (id+1) + '. Twitch: ' + current.twitch_username + ' Level: ' + current.level + '\n');
}, '')

use named regex groups to output an array of matches

I'm trying to get the hang of named capturing groups.
Given a string
var a = '{hello} good {sir}, a [great] sunny [day] to you.';
I'd like to output an array which maintains the integrity of the sentence (complete with punctuation, spaces, etc) so I can reassemble the sentence at a later time:
[
{
group: "braces",
word: "hello"
},
{
group: "other",
word: " good " <-- space on either side is maintained
},
{
group: "braces",
word: "sir"
},
{
group: "other",
word: ", a "
},
{
group: "brackets",
word: "great"
},
{
group: "other",
word: " sunny "
},
{
group: "brackets",
word: "day"
},
{
group: "other",
word: " to you."
},
]
I'm using named capturing groups to try and output this. <braces> captures any text within {}, <brackets> captures any text within [], and <others> captures anything else (\s,.\w+):
var regex = /(?<braces>\{(.*?)\})(?<brackets>\[(.*?)\])(?<others>\s,.\w+)?/g;
console.log(a.match(regex)); outputs nothing.
If I remove <others> group,
var regex = /(?<braces>\{(.*?)\})(?<brackets>\[(.*?)\])?/g;
console.log(a.match(regex)); outputs ["{hello}", "{sir}"]
Question: How do I use capturing groups to find all instances of named groups and output them like the above desired array?
A regex match object will only contain one string for a given named capture group. For what you're trying to do, you'll have to do it in two steps: first separate out the parts of the input, then map it to the array of objects while checking which group was captured to identify the sort of group it needs:
const str = '{hello} good {sir}, a [great] sunny [day] to you.';
const matches = [...str.matchAll(/{([^{]+)}|\[([^\]]+)\]|([^[{]+)/g)]
.map(match => ({
group: match[1] ? 'braces' : match[2] ? 'brackets' : 'other',
word: match[1] || match[2] || match[3]
}));
console.log(matches);

Sequelize multi table association query with ORs

I have to find a field in different tables, that is, I have to check if the search is in different fields of the Customer table, in different fields of the Shops table, and in different fields of the ContactPerson table
The Customer and Persons and Customer Shops tables are 1-N and are associated
My "search" variable is what I wanna find.
This is my code
CustomerPersonsRelation()
CustomerShop()
var result = await CustomerModel.findAll({
...params,
include: [
{model : ShopModel},
{model: ContactPersonModel}
]
})
All is imported don't worry about that.
My Params are these:
{
where: {
$or: [
{
'$Customer.customer_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_fiscal_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_responsable_name$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_responsable_phone$': { $like: '%' + search + '%' },
},
{
'$Customer.customer_web$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_name$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_phone$': { $like: '%' + search + '%' },
},
{
'$Shops.shop_mobile$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_name$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_phone$': { $like: '%' + search + '%' },
},
{
'$ContactPersons.contactp_mobile$': { $like: '%' + search + '%' },
}
]
},
limit: 3
})
}
But that returns this error:
Error : SequelizeDatabaseError: The multi-part identifier "ContactPersons.contactp_mobile" could not be bound. (And this error for all related fields.)
What I can do for that works?
Solved!
After a lot of tests i discovered the error was not in relation and was not in the OR, was in the LIMIT.
After search i solved this adding duplicating: false in includes.
The final code is this:
var result = await CustomerModel.findAll({
include: [
{model : ShopModel, require: true, duplicating: false},
{model: ContactPersonModel, require: true, duplicating: false}
],
...params,
raw
})

Convert Java tokenizing regex into Javascript

As an answer to my question Tokenizing an infix string in Java, I got the regex (?<=[^\.a-zA-Z\d])|(?=[^\.a-zA-Z\d]. However, now I'm writing the same code in Javascript, and I'm stuck as to how I would get a Javascript regex to do the same thing.
For example, if I have the string sin(4+3)*2, I would need it parsed into ["sin","(","4","+","3",")","*","2"]
What regex would I use to tokenize the string into each individual part.
Before, what I did is I just did a string replace of every possible token, and put a space around it, then split on that whitespace. However, that code quickly became very bloated.
The operators I would need to split on would be the standard math operators (+,-,*,/,^), as well as function names (sin,cos,tan,abs,etc...), and commas
What is a fast, efficient way to do this?
You can take advantage of regular expression grouping to do this. You need a regex that combines the different possible tokens, and you apply it repeatedly.
I like to separate out the different parts; it makes it easier to maintain and extend:
var tokens = [
"sin",
"cos",
"tan",
"\\(",
"\\)",
"\\+",
"-",
"\\*",
"/",
"\\d+(?:\\.\\d*)?"
];
You glue those all together into a big regular expression with | between each token:
var rtok = new RegExp( "\\s*(?:(" + tokens.join(")|(") + "))\\s*", "g" );
You can then tokenize using regex operations on your source string:
function tokenize( expression ) {
var toks = [], p;
rtok.lastIndex = p = 0; // reset the regex
while (rtok.lastIndex < expression.length) {
var match = rtok.exec(expression);
// Make sure we found a token, and that we found
// one without skipping garbage
if (!match || rtok.lastIndex - match[0].length !== p)
throw "Oops - syntax error";
// Figure out which token we matched by finding the non-null group
for (var i = 1; i < match.length; ++i) {
if (match[i]) {
toks.push({
type: i,
txt: match[i]
});
// remember the new position in the string
p = rtok.lastIndex;
break;
}
}
}
return toks;
}
That just repeatedly matches the token regex against the string. The regular expression was created with the "g" flag, so the regex machinery will automatically keep track of where to start matching after each match we make. When it doesn't see a match, or when it does but has to skip invalid stuff to find it, we know there's a syntax error. When it does match, it records in the token array which token it matched (the index of the non-null group) and the matched text. By remembering the matched token index, it saves you the trouble of having to figure out what each token string means after you've tokenized; you just have to do a simple numeric comparison.
Thus calling tokenize( "sin(4+3) * cos(25 / 3)" ) returns:
[ { type: 1, txt: 'sin' },
{ type: 4, txt: '(' },
{ type: 10, txt: '4' },
{ type: 6, txt: '+' },
{ type: 10, txt: '3' },
{ type: 5, txt: ')' },
{ type: 8, txt: '*' },
{ type: 2, txt: 'cos' },
{ type: 4, txt: '(' },
{ type: 10, txt: '25' },
{ type: 9, txt: '/' },
{ type: 10, txt: '3' },
{ type: 5, txt: ')' } ]
Token type 1 is the sin function, type 4 is left paren, type 10 is a number, etc.
edit — if you want to match identifiers like "x" and "y", then I'd probably use a different set of token patterns, with one just to match any identifiers. That'd mean that the parser would not find out directly about "sin" and "cos" etc. from the lexer, but that's OK. Here's an alternative list of token patterns:
var tokens = [
"[A-Za-z_][A-Za-z_\d]*",
"\\(",
"\\)",
"\\+",
"-",
"\\*",
"/",
"\\d+(?:\\.\\d*)?"
];
Now any identifier will be a type 1 token.
I don't know if this will do everything of what you want to achieve, but it works for me:
'sin(4+3)*2'.match(/\d+\.?\d*|[a-zA-Z]+|\S/g);
// ["sin", "(", "4", "+", "3", ")", "*", "2"]
You may replace [a-zA-Z]+ part with sin|cos|tan|etc to support only math functions.
Just offer up a few possibilities:
[a-zA-Z]+|\d+(?:\.\d+)?|.

Categories

Resources