Find matching strings from array with multiple params - javascript

Not sure how to implement such a search with params as values and different params count. Looks like I need Regex & match. But params are not hardcoded in my matching (possible URLs array) - they are dynamic, and param value can be 0, 100, 777 and etc.
For example, I have such an array of strings to match:
[
'urlA/someId1',
'urlA/someId1/someSubUrlA/someId2',
'urlB/someId1/someId2'
'urlB/someId1/someSubUrlB/someId2'
]
ps: I can edit this array, so for example surround params with {} etc.
and when I try to run a search for: http://example.com/urlA/100/someSubUrlA/200
it should return urlA/someId1/someSubUrlA/someId2
when I try to run a search for: http://example.com/urlA/150
it should return urlA/someId1
and from what I can see I can use Regex & .match with .find(). But I'm confused about how to write custom matcher with custom parameters & their count. Is it possible somehow in JS?

Basically you want that given a url to find the abstract representation of it. Right?
let data = [
'urlA/someId1',
'urlA/someId1/someSubUrlA/someId2',
'urlB/someId1/someId2',
'urlB/someId1/someSubUrlB/someId2'
];
function finder(url) {
let afterDomain = url.match(/http:\/\/[^\/]*\.[^\/]*\/(.*)/)[1];
let matcher = afterDomain.replace(/\d+/g, "[^\/]+");
return data.find(x => (new RegExp(matcher)).test(x))
}
finder("http://example.com/urlA/100/"); // "urlA/someId1"
finder("http://example.com/urlA/100/someSubUrlA/200"); // "urlA/someId1/someSubUrlA/someId2"

Related

looking for a regex pattern to remove contents in a JSON string

I have a JSON string something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000",
"clearingbankAccinfo":"Westpac"}]
The issue is we have to clear the bank info, and that can be any value.
What we know for sure is it would come at the end of the string.
I need a regex pattern to remove this clearingbankAccInfo so that it looks something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000"}]
Unfortunately I would have not accepted this as input itself but this information comes from a diff process and I have no control over what they pass.
I have tried:
String str=str.replace(',"clearingbankAccInfo":\g[a-zA-Z0-9_:]\g+', '' )
But it doesn't work correctly
If you're working with something like JSON regex is the wrong solution. Simply parse the stringified data, and loop over it with something like map to extract and return the correct data. Then you can just make a string again out of that data.
const str = '[{"name": "Dukes","lastname": "Chavez","salary": "10000","clearingbankAccinfo": "Westpac"},{"name": "Bob","lastname": "Smith","salary": "20000","clearingbankAccinfo":"Lloyds"}]';
// Here we're creating a new variable called `newData` to hold
// the transformed data. We parse the data string and iterate over it
// (because it's now an array) with `map` which is an array method.
// With each iteration we take the object, grab the clearingBankAccinfo
// and just return everything else.
const newData = JSON.parse(str).map(obj => {
const { clearingbankAccinfo, ...rest } = obj;
return rest;
});
console.log(newData);
console.log(JSON.stringify(newData));
Additional documentation
Rest parameters
Working with JSON
Destructuring assignment
str=str.replace(/,?"clearingbankAccinfo":"\w+"/g, '');

Comparing a bypass attempt to a string javascript

From the name of the question this might seem like an easy task, but im a beginner. What I need to do is compare a string (user input, I already have it), with a list of words. Basically if the user inputs bluuexel I still want to have the program to interpret it as blue (im actually making a bot to censor words and just entering random stuff is a common strategy to bypass censors). I was going to sort and delete duplicates but then I realized that "ass" would become "as" and this strategy wouldnt be as applicable.
For analyzing strings, you may use String.prototype.includes to see if a substring is located in a string or other options such as Regex for exact matches. Many approaches may be applied, but this example may get you started. String.prototype.includes
For replacing other strings, you something such as String.prototype.replace. String.prototype.replace
Since you also tagged this post under Node.js, to receive user input from the command prompt. Use may use the Node.js readline module. Readline
Beware of the comparison item.value == search may cause unexpected type coercion also. That is why we are using ====.
Note
Your question is a little broad, but it seems you are trying to compare strings against other strings. It would help to provide some code so we get a sense of what you are trying to accomplish.
var items = [{
value: "one"
},
{
value: "bluuexel"
}
]
// Accept a search string term variable
unique = (search) => {
// Iterate through the object items
// Some: Determines whether the specified callback function
// returns true for any element of an array.
return items.some(item => {
// Return if item.value is equal to the search string, beware of
// Comparison item.value == search may cause unexpected type
// coercion. So we use ===
return item.value === search
});
};
// Accept a search string term variable
contains = (search) => {
// Iterate through the object items
// Some: Determines whether the specified callback function
// returns true for any element of an array.
return items.some(item => {
// Includes: Returns true if searchString
// appears as a substring of the result of converting
// this object to a String, at one or more positions that
// are greater than or equal to position; otherwise, returns false.
// Return if item.value contains equal to the search string
return item.value.includes(search)
});
};
console.log('Unique:', unique('bluuexel'), '=> bluuexel');
console.log('Contains:', contains('bluu'), '=> bluu');
console.log('Contains:', contains('bluu2'), '=> bluu2');
console.log('Unique:', unique('one'), '=> one');
console.log('Unique:', unique('one2'), '=> one2');
Now for removing words from an array or duplicates, also many other approaches. But here is a simple example.
We also make use of the Spread syntax (...) allows an iterable such as an array expression or string to be expanded in short terms. Spread
The Set constructor lets you create Set objects that store unique values of any type, whether primitive values or object references. Set
// Defined list of an array of words
let words = ['bluuexel', 'bluuexel2', 'bluuexel'];
// ... Spread operator to iterate over array elements in array "words"
console.log('Removed (Duplicates)', words);
let removed = [...new Set(words)];
// Output unique only words, from new array named "removed"
console.log('Removed (Non Duplicates)', removed);
Putting it together to remove some banned words and also duplicates.
// Filtering words and duplicates
// Word List
let words = [ 'one',
'one',
'two',
'two2',
'ass',
'as']
// Banned Words
let banned = ['ass']
// Contains word, accepts a string and a list as an array
contains = (search, list) => {
// Determine if the list has a string
return list.some(item => {
return item.includes(search)
});
};
// Function for filtering, and removing duplicates and banned words
function filter() {
// Remove duplicates first, update word list
words = [...new Set(words)];
// Iterate through banned word list
banned.forEach((word) => {
// Output that banned word was found
console.log('Found Banned (Word):', word)
if (contains(word, words)) {
// Update final word list
words.splice(words.indexOf(word), 1);
}
})
}
console.log('Previous Results', words)
// Run filter function
filter()
// Output results
console.log('Final Results', words)

MongoDB search string in array of objects

I have a structure in MongoDB that have different amounts of items in an array called "items". To make the search, I am using the following command, which first turns the contents into a string, as in this.items there is a different structure depending on the object:
db.getCollection('docs').find.('JSON.stringify(this.items[0].value).toLowerCase().indexOf("text")!=-1')
My problem is that as I do not know the amount of items that each document has, I would have to use a wildcard as this.items[*].value, but it does not work.
Does anyone know any solution, or have another idea for this?
You can use the $elemMatch (https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/)
db.docs.find({items: {$elemMatch: {value: {$regex : "text"}}}});
So this query will find all documents with an item in the items array that contain the string "text" in the value property, after this operation you can count how much items the document has.
You can use dot notation of items.value to target the value field of all items elements, and a regular expression to perform the case-insensitive sub-string match:
db.getCollection('docs').find({ 'items.value': /text/i })
You can iterate each document and apply the indexOf, something like this..
var cursor = db.getCollection('docs').find({}); // get all docs
var newOut = []; // new array of items if match with some condition
while ( cursor.hasNext() ){ // iterate all docs
var doc = cursor.next(); // get the document in focus
doc.items.forEach(function(item){ // iterate the items of doc.items
if ( item.toLowerCase().indexOf("text") !== -1 ) // check if text exists in array
newOut.push(item); // add to new array
});
};
printjson(newOut);

How do I "unstringify" a value within an array with javascript?

I'm building a dynamic search query for a Mongo database.
In short, and not directly related to the question... it looks like this:
var searchCriteria = {}; <-- start with empty object
return db.users.find(searchCriteria,
{ sort: { username: 1 }
});
The values for searchCriteria come from a search form, basically like this:
var filter = $(form).find('select[name=filter]').val();
var query = $(form).find('[name=query]').val();
searchCriteria[filter] = query <-- Using a dynamic key
Example output from the form:
console.log(searchCriteria);
>> { username: "jdoe" }
So here's my hangup. I need to "unstringify" the query within the searchCriteria, and turn it into this:
>> { username: /jdoe/ }
I've tried replace, among other things, but it keeps ending up as a string value. I need the /query/ in that format for the Mongo find query.
Any suggestions? Thank you :)
You can easily turn a string into a RegExp object by using new Regex(string).
Note that this is bound to have some security issues somewhere if you're passing in user input, but new RegExp shouldn't allow any arbitrary JS to run, but it could still crash your code by being an invalid Regex.
Source (MDN)

Data-attribute retrieval and parsing javascript

I am new to javascript programming and i am stuck with data-attribute retrieval.
The below link is a bit useful for people using jQuery
store and retrieve javascript arrays into and from HTML5 data attributes
I would like to do the same with vanilla js. With the help of custom data-attributes i would like to create objects & array.
<div id="getAnimation"
data-r="564"
data-c="96"
data-custom="x:0;y:0;z:0;rotationX:0;rotationY:0;rotationZ:0;scaleX:0.75;scaleY:0.75; skewX:0;skewY:0;opacity:0;transformPerspective:600;transformOrigin:50% 50%;"
data-s="700"
data-st="1400"
</div>
Do HTML5 custom data attributes “work” in IE 6?
The above link helps in getting data attributes very well but how can be filter the string in data-custom or straight create an object of data-custom.
If someone know a library to do this please let me know
Here are a couple quick functions which will let you store, retrieve and delete any JSON-able data to a data attribute
function setData(node, data_name, data_value) {
node.dataset[data_name] = JSON.stringify(data_value);
}
function getData(node, data_name) {
return JSON.parse(node.dataset[data_name]);
}
function delData(node, data_name) {
return delete node.dataset[data_name];
}
Then to write an Array to #getAnimation in data-fizz
// variables to use
var elm = document.getElementById('getAnimation'),
foo = [1, 2, 3, 'a', 'b', 'c'];
// store it
setData(elm, 'fizz', foo);
// retrieve it
var bar = getData(elm, 'fizz');
// look what we have
console.log(bar); // [1, 2, 3, "a", "b", "c"]
Requires IE 11+ because I use node.dataset, if you change this to the methods node.setAttribute, node.getAttribute and node.removeAttribute as used, the requirement drops to IE 8+ because of the JSON.stringify and JSON.parse
That particular example is quite straight forward: It's a series of name:value pairs separated with semicolons. So you can get an array of the pairs using split, and then get the name and valid separate using split again. If you want to create properties on an object using those names and values, you can do that with bracketed notation:
// Get the value
var val = theElement.getAttribute("data-custom");
// Split it into fields on `;` (with optional whitespace on either side)
var fields = val.split(/\s*;\s*/);
// Create a blank object
var obj = {};
// Loop through the fields, creating object properties:
fields.forEach(function(field) {
// Split the field on :, again with optional whitespace either side
var parts = field.split(/\s*:\s*/);
// Create a property on the object using the name, and assigning the value
obj[parts[0]] = parts[1];
});
I'm using String#split there, giving it a regular expression to tell it where the split up the string.
In the resulting object, with just the code above, the property values will all be strings. For instance, obj.scaleX will be the string "0.75". If you need them as numbers, you can convert them to numbers in any of several ways:
parseFloat, which will convert as many characters as it can but ignore trailing characters. so parseFloat("0.75foo") is 0.75, not an error.
Number, which will not be tolerant like parseFloat, Number("0.75foo") is NaN, not 0.75.
Applying any mathematical operator, the unary + is common: +"0.75" is 0.75.
So rather than just grabbing the values as strings, we could check to see if they look like they might be numbers and convert them if so:
// Loop through the fields, creating object properties:
fields.forEach(function(field) {
// Split the field on :, again with optional whitespace either side
var parts = field.split(/\s*:\s*/);
// Does the value look like a number?
if (/(?:^\d+$)|(?:^\d+\.\d+$)/.test(parts[1])) {
// Yes
obj[parts[0]] = +parts[1];
}
else {
// No
obj[parts[0]] = parts[1];
}
});
That assumes . as the decimal separator, and assumes there won't be a thousands separator.
Side note: Above I've used Array#forEach, which is an ES5 feature not present on older browsers. forEach can be "shimmed" on older browsers, though. You can see all sorts of ways of looping through arrays in this answer here on SO.

Categories