how to check: if array includes specific text properly? - javascript

I am struggling with doing an array search that includes a piece of text that must include back slashes in it. I have tried includes(''); negating includes(''); and also trying similar using indexOf('').
I have a simple array, with at maximum four values; typically it has two, here is how it typically looks:
{tks: Array(2)}
tks: Array(2)
0: "https://mycoolwebsite.net/arcgis/rest/services"
1: "https://mycoolwebsite.com/arcgis/rest/services"
length: 2
__proto__: Array(0)
__proto__: Object
Here are the simple checks I'm trying to do: My second check with *includes* 'wdt' text seems to be working so I assume it's something with the backslashes. Anyway I can handle this? I'm perplexed why my if and else both get hit with the first check below using back slashes... I added the negating on the else to double check.. with and without that in the else, else is always hit.
// right before doing the search I am building the array, just to add more context
for (let i = 0; i < coolObj.length; i++) {
if (coolObj[i].url){
tr = coolObj[i].url;
tks.push(tr);
console.log({tks});
}
}
console.log({tks}); // consoles as I have included above ^
if (tks.includes('/arcgis/rest/services')) {
console.log({tks});
} else if (!tks.includes('/arcgis/rest/services')) {
console.log({tks});
console.log('does not include correct url');
aT = '/arcgis/rest/services';
lP = false;
filterAt(aT);
}
if (tks.includes('wdt')) {
console.log({tks});
}else {
console.log({tks});
wT = 'wdt';
filterWt(wT);
}

From the MDN docs: The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.
You have to test the strings using String.prototype.includes within the array elements thus:
const arr = ["https://mycoolwebsite.net/arcgis/rest/services", "https://mycoolwebsite.com/arcgis/rest/services"];
arr.forEach(el => {
if (el.includes('/arcgis/rest/services')) {
console.log(el, ': includes url');
}
else {
console.log('does not include correct url');
}
if (el.includes('wdt')) {
console.log(el, ': includes wdt');
} else {
console.log('does not include correct wdt');
}
});

Related

cli input parsing for node.js

i am trying to make a CLIish server in node.js.
but I need a way to parse a string and run a function from an object.
what I mean is... I don't want to nest a million switch statements just to have the commands I need.
using 2 other StackOverflow answers, I got 1 part done. inputs.
now i just need to figure out how to figure ou where the command stops and the input begins.
example:
inputting do say user:Yimmee msg:"well hello" "something random":yes
I need to separate do say and the inputs.
this is what i started with, but I do not know how to finish it.
function command(command, usable){
//usable is the object holding the commands that can be used.
//here I set commandMain to the part of command that is the command
/*and where commandInput is too. and I'm not forcing you,
but is preferably to be converted to an object.*/
var commandSplit = [];
do{
var match = (/[^ "]+|"([^"]*)"/gim).exec(commandMain);
if(match != null){
commandSplit.push(match[1] ? match[1] : match[0]);
}
}while (match != null);
var reach = `usable`;
commandSplit.forEach((to, nu)=>{
if(nu === commandSplit.length - 1){
reach += `["_${to}"]`;
}else{
reach += `["${to}"]`;
}
});
console.log(reach);
try{
return eval(reach)(commandInputs);
}catch(error){
return false;
}
}
Note I gave up a little, there will be some ridiculous errors.
big fat edit::::::::::::::::::::::L:::::::
idk how in the world process.argv works, and looking in one of the answers, i know how to set it.
but i am using a live websocket for this.
Unless this is an exercise, I'd strongly recommend not to implement your own command and argument parser. Use one of the existing libraries. A quick web search for "node cli library" yields a lot of results, including comparisons.
The libraries range from tiny and simple like minimist, very popular ones like yargs or commander, to heavier ones like oclif.
I'd also recommend checking the Command-line utilities section of Sindre Sorhus' Awesome Node.js list.
What you are doing is passing options and arguments to a program. You can use process.argv to get these.
It's always good to have useful error messages and command line documentation. Hence, if you're distributing to users, a more robust library for this purpose is worth an extra dependency. Widely used is yargs, see their website at https://www.npmjs.com/package/yargs for some examples.
If you want to do it using the basic process.argv, here's a solution:
This is your command in a format most people are used to: node some.js --user Yimmee --msg "well hello" --random
And the implementation
let arguments = process.argv.slice(2); // this removes `node` and the filename from arguments list
console.log(arguments)
switch (arguments[0]) { // check that `say` is the first "command"
case 'say':
let options = process.argv.slice(3); // get the stuff after `say`
let optionsObject = {} // key-value representation
if (options.indexOf("--user") != -1) { // if it exists
optionsObject.user = options[options.indexOf("--user")+1]
}
else {
// you can throw an error here
}
if (options.indexOf("--msg") != -1) { // if it exists
optionsObject.msg = options[options.indexOf("--msg")+1]
}
if (options.indexOf("--random") != -1) { // if it exists
optionsObject.random = true
}
console.log(optionsObject) // you can use optionsObject for your program
break;
default:
console.log("Invalid command");
}
EDIT: If this is happening inside the code as a function call, you can adapt above code:
function test(argsString) {
let arguments = argsString.split(/ (?=(?:(?:[^"]*"){2})*[^"]*$)/); // split the string into an array at the spaces
// ^ regex from https://stackoverflow.com/questions/23582276/
console.log(arguments)
switch (arguments[0]) { // check that `say` is the first "command"
case 'say':
let options = arguments.slice(1); // get the stuff after `say`
let optionsObject = {} // key-value representation
if (options.indexOf("--user") != -1) { // if it exists
optionsObject.user = options[options.indexOf("--user") + 1]
}
else {
// you can throw an error here
}
if (options.indexOf("--msg") != -1) { // if it exists
optionsObject.msg = options[options.indexOf("--msg") + 1]
}
if (options.indexOf("--random") != -1) { // if it exists
optionsObject.random = true
}
console.log(optionsObject) // you can use optionsObject for your program
break;
default:
console.log("Invalid command");
}
}

Check Javascript nested obj value exists with unknown key

The following is used to build up a object array:
var users = {};
var user = {};
user[socket.id] = data.username;
if(users[data.roomname]){
// Room already exists - check user already exists
// if data.username does not value exist is users then:
users[data.roomname].push(user);
}
else{
// New room
users[data.roomname] = [user];
}
Over a few iterations we get something like this:
console.log ( 'Users: ', users );
users { RoomABC:
[ { YidwzgUHPHEGkQIPAAAD: 'Mr Chipps' },
{ 'JG-gtBMyPm0C1Hi1AAAF': 'Mr T' },
{ '2JFGMEdPbgjTgLGVAAAH': 'Mr Chipps' }, ] }
The issue is trying to ensure that each username is unique, so Mr Chipps should not be added again if that name already exists.
The examples I have seen Assume the keys are known. I have tried a number of things including some, indexOf but I am not able to get a simple 'does UserX already exist' to work.
The following is the latest block of code I tried to only add the user if not already present in the obj array. This works, but it seems very clunky to me; nested loops to get at the correct level to check the value and set a counter if a match found, then check the counter to decide if a match was found or not:
if(users[data.roomname]){
// Room already exists - check user already exists
let found = 0;
// Nested loop - seems a little clunky but it works
Object.keys(users[data.roomname]).forEach(key => {
Object.keys(users[data.roomname][key]).forEach(key2 => {
if ( users[data.roomname][key][key2] === data.username ) {
found++;
}
});
});
if ( found == 0 ) {
users[data.roomname].push(user);
}
}
I keep thinking surely there is neat one-liner that can do this check for the existence but I cant get any to work.
You could check the values instead of using the keys and exit early if a name is found
if (users[data.roomname]) {
if (!Object.values(users[data.roomname]).some(v => Object.values(v).some(n => n === data.username))) {
users[data.roomname].push(user);
}
}

Javascript Equalize Element From Array

Guys I want to get an element from array. Here:
Follower:
{ follower:
[ 5edfe8f3bfc9d677005d55ca,
5edfe92fbfc9d677005d55cc,
5ee2326cc7351c5bb0b75f1a ],
user id:
5edfe92fbfc9d677005d55cc
The process:
if(follower == user){
console.log("sdasdsad")
}else{
console.log("no")
}
But when I do it it always returns as no.
Also this is the codes of===> Nodejs Follow System Not Working Properly
It is a nodejs project. So please look at the above link.
When I do
if(follower.includes(user)){
It gives the error of:
TypeError: Cannot read property 'includes' of null
And when I try to change some I get this error:
TypeError: takip.includes is not a function
Guys so thats why I say please look at the above code.
So how to equalize them?
As other peoples said earlier the follower itself is a property which its value is an array itself, so if you want to check whether an item exists within it or not you can check it with includes(), if it exists it will return true otherwise it will return false.
const follow = {
follower: ["5edfe8f3bfc9d677005d55ca",
"5edfe92fbfc9d677005d55cc",
"5ee2326cc7351c5bb0b75f1a"
]
}
const user = "5edfe92fbfc9d677005d55cc";
if (follow.follower.includes(user)) {
console.log("sdasdsad")
} else {
console.log("no")
}
But if you looking to find the exact position of the item within that array you can find it with indexOf(). If the item does not exist within the array it will return -1, otherwise, it will return the index of that item within the array.
const follow = {
follower: ["5edfe8f3bfc9d677005d55ca",
"5edfe92fbfc9d677005d55cc",
"5ee2326cc7351c5bb0b75f1a"
]
}
const user = "5edfe92fbfc9d677005d55cc";
console.log(follow.follower.indexOf(user));
You are trying to compare a string to an array so it will never pass the if statement.
If you change your if to be if ( follower.includes(user)) { then it will search the array for the string.
var follower = [
'5edfe8f3bfc9d677005d55ca',
'5edfe92fbfc9d677005d55cc',
'5ee2326cc7351c5bb0b75f1a'
]
var user = '5edfe92fbfc9d677005d55cc'
// This will always fail as follower is an array not a string
if (follower.includes(user)){
console.log("sdasdsad")
} else {
console.log("no")
}
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
Looks like follower is a property. You can use this solution:
objectName.follower.forEach(item =>
if (item == user) console.log(`${item} is the answer`);
);
This way, javascript will go through all of the elements in the array and print it out if it is matching with your user variable.
You can also use for loop or while loop for the same process, however, since you're using an array, forEach will be much more useful.
If this was not your question and I misunderstood your question, let me know, I'll see if I can help.
I hope this helps
var obj = {
follower: [ '5edfe8f3bfc9d677005d55ca',
'5edfe92fbfc9d677005d55cc',
'5ee2326cc7351c5bb0b75f1a'
]
};
var userId = '5edfe92fbfc9d677005d55cc';
function searchUser(object, user){
if(obj.follower.includes(user)){
return object.follower.filter(x => x == user);
} else {
return 'no';
}
};
console.log(searchUser(obj, userId));
You can use Array.protorype.some() to check if user exists in the follower array.
const obj = {
follower: [
"5edfe8f3bfc9d677005d55ca",
"5edfe92fbfc9d677005d55cc",
"5ee2326cc7351c5bb0b75f1a"
]
}
const user = "5edfe92fbfc9d677005d55cc";
if(obj.follower.some(item => item === user)) {
console.log("found")
} else{
console.log("no")
}
You can also get the item with Array.protorype.find() with the same way as above, just assign it to a variable
Array.prototype.some
Array.prototype.find

Add an object to JSON

I have a settings.json file that contains following data (where 123456789 is a distinct user id):
{
"123456789":
{"button_mode":true}
}
So what I need to do is push a similar id: {button_mode: value} object to this JSON file in case there's no entry for current user's id. I tried to use lcSettings.push() but obviously it did not work since I have an object, not an array. When I put square brackets instead of curly ones to make it an array, my code doesn't do anything at all.
Here's a snippet of it (Node.js):
var lcSettings = JSON.parse(fs.readFileSync('./settings.json', 'utf8'));
var currentUser = id;
if (lcSettings.hasOwnProperty(currentUser)) {
// in case settings.json contains current user's id check for button_mode state
if (lcSettings[currentUser].button_mode == true) {
// if button_mode is on
} else
if (lcSettings[currentUser].button_mode == false) {
// if button_mode is off
}
} else {
// in case there's no entry for current user's id
// here's where I need to push the object for new user.
}
fs.writeFileSync('./settings.json', JSON.stringify(lcSettings))
Does anybody have ideas on how it can be implemented? Any help appreciated.
You can use bracket notation to add a dynamic property to an object:
lcSettings[id] = { button_mode: false };
You may also want to verify that settings.json is not empty otherwise the JSON.parse() will fail. In this case, you would want to initialize lcSettings to an empty object (lcSettings = {}) so the above will work.
To 'push' elements to an object you simply define them, as in
object['123456789'] = { button_mode: true };

Comparing 2 Json Object using javascript or underscore

PS: I have already searched the forums and have seen the relevant posts for this wherein the same post exists but I am not able to resolve my issue with those solutions.
I have 2 json objects
var json1 = [{uid:"111", addrs:"abc", tab:"tab1"},{uid:"222", addrs:"def", tab:"tab2"}];
var json2 = [{id:"tab1"},{id:"new"}];
I want to compare both these and check if the id element in json2 is present in json1 by comparing to its tab key. If not then set some boolean to false. ie by comparing id:"tab1" in json2 to tab:"tab1 in json1 .
I tried using below solutions as suggested by various posts:
var o1 = json1;
var o2 = json2;
var set= false;
for (var p in o1) {
if (o1.hasOwnProperty(p)) {
if (o1[p].tab!== o2[p].id) {
set= true;
}
}
}
for (var p in o2) {
if (o2.hasOwnProperty(p)) {
if (o1[p].tab!== o2[p].id) {
set= true;
}
}
}
Also tried with underscore as:
_.each(json1, function(one) {
_.each(json2, function(two) {
if (one.tab!== two.id) {
set= true;
}
});
});
Both of them fail for some test case or other.
Can anyone tell any other better method or outline the issues above.
Don't call them JSON because they are JavaScript arrays. Read What is JSON.
To solve the problem, you may loop over second array and then in the iteration check if none of the objects in the first array matched the criteria. If so, set the result to true.
const obj1 = [{uid:"111", addrs:"abc", tab:"tab1"},{uid:"222",addrs:"def", tab:"tab2"}];
const obj2 = [{id:"tab1"},{id:"new"}];
let result = false;
for (let {id} of obj2) {
if (!obj1.some(i => i.tab === id)) {
result = true;
break;
}
}
console.log(result);
Unfortunately, searching the forums and reading the relevant posts is not going to replace THINKING. Step away from your computer, and write down, on a piece of paper, exactly what the problem is and how you plan to solve it. For example:
Calculate for each object in an array whether some object in another array has a tab property whose value is the same as the first object's id property.
There are many ways to do this. The first way involves using array functions like map (corresponding to the "calculate for each" in the question, and some (corresponding to the "some" in the question). To make it easier, and try to avoid confusing ourselves, we'll do it step by step.
function calculateMatch(obj2) {
return obj2.map(doesSomeElementInObj1Match);
}
That's it. Your program is finished. You don't even need to test it, because it's obviously right.
But wait. How are you supposed to know about these array functions like map and some? By reading the documentation. No one help you with that. You have to do it yourself. You have to do it in advance as part of your learning process. You can't do it at the moment you need it, because you won't know what you don't know!
If it's easier for you to understand, and you're just getting started with functions, you may want to write this as
obj2.map(obj1Element => doesSomeElementInObj1Match(obj1Element))
or, if you're still not up to speed on arrow functions, then
obj2.map(function(obj1Element) { return doesSomeElementInObj1Match(obj1Element); })
The only thing left to do is to write doesSomeElementInObj2Match. For testing purposes, we can make one that always returns true:
function doesSomeElementInObj2Match() { return true; }
But eventually we will have to write it. Remember the part of our English description of the problem that's relevant here:
some object in another array has a tab property whose value is the same as the first object's id property.
When working with JS arrays, for "some" we have the some function. So, following the same top-down approach, we are going to write (assuming we know what the ID is):
In the same way as above, we can write this as
function doesSomeElementInObj2Match(id) {
obj2.some(obj2Element => tabFieldMatches(obj2Element, id))
}
or
obj2.some(function(obj2Element) { return tabFieldMatches(obj2Element, id); })
Here, tabFieldMatches is nothing more than checking to make sure obj2Element.tab and id are identical.
We're almost done! but we still have to write hasMatchingTabField. That's quite easy, it turns out:
function hasMatchingTabField(e2, id) { return e2.tab === id; }
In the following, to save space, we will write e1 for obj1Element and e2 for obj2Element, and stick with the arrow functions. This completes our first solution. We have
const tabFieldMatches = (tab, id) { return tab === id; }
const hasMatchingTabField = (obj, id) => obj.some(e => tabFieldMatches(e.tab, id);
const findMatches = obj => obj.some(e => hasMatchingTabField(e1, obj.id));
And we call this using findMatches(obj1).
Old-fashioned array
But perhaps all these maps and somes are a little too much for you at this point. What ever happened to good old-fashioned for-loops? Yes, we can write things this way, and some people might prefer that alternative.
top: for (e1 of obj1) {
for (e2 of (obj2) {
if (e1.id === e2.tab) {
console.log("found match");
break top;
}
}
console.log("didn't find match);
}
But some people are sure to complain about the non-standard use of break here. Or, we might want to end up with an array of boolean parallel to the input array. In that case, we have to be careful about remembering what matched, at what level.
const matched = [];
for (e1 of obj1) {
let match = false;
for (e2 of obj2) {
if (e1.id === e2.tab) match = true;
}
matched.push(match);
}
We can clean this up and optimize it bit, but that's the basic idea. Notice that we have to reset match each time through the loop over the first object.

Categories

Resources