PHP-like string parsing - string

I'm writing a mini-console of sorts and I'm trying to figure out how to extract things from a link. For example, in PHP this is a request variable
so:
http://somelink.com/somephp.php?variable1=10&variable2=20
Then PHP figures out the url parameters and assigns them to a variable.
How would I parse something like this in Swift?
So, given the string I'd want to take: variable1=10 and variable2=20 etc, is there a simple way to do this? I tried googling around but didn't really know what I was searching for.
I have a really horrible hacky way of doing this but it's not really extendable.

You’d be wanting NSURLComponents:
import Foundation
let urlStr = "http://somelink.com/somephp.php?variable1=10&variable2=20"
let components = NSURLComponents(string: urlStr)
components?.queryItems?.first?.name // Optional("variable1")
components?.queryItems?.first?.value // Optional("10")
You might find it helpful to add a subscript operator for the query items:
extension NSURLComponents {
subscript(queryItemName: String) -> String? {
// of course, if you do this a lot,
// cache it in a dictionary instead
for item in self.queryItems ?? [] {
if item.name == queryItemName {
return item.value
}
}
return nil
}
}
if let components = NSURLComponents(string: urlStr) {
components["variable1"] ?? "No value"
}

Related

get title from Zotero item

Still very new to Rust, trying to understand how to extract the title of a JournalArticle using the Zotero crate.
I've got this, and can confirm the item is retrieved successfully:
let zc = ZoteroCredentials::new();
let z = ZoteroInit::set_user(&zc.api_id, &zc.api_key);
let item = z.get_item(item_id, None).unwrap();
From here, I see that an item.data is an ItemType, specifically a JournalArticleData. But I'm fundamentally not quite understanding how to either a) serialize this to JSON, or b) access .title as a property.
For context, this would be the result of a Rocket GET route.
Any help would much appreciated!
It sounds like the part you're missing is how to use pattern matching on an enum. I'm not familiar with zotero so this is all based on the docs, with verbose type annotations to be explicit about what I think I'm doing:
use zotero::data_structure::item::{Item, ItemType, JournalArticleData};
let item: Item = z.get_item(item_id, None).unwrap();
// Now we must extract the JournalArticle from the ItemType, which is an enum
// and therefore requires pattern matching.
let article: JournalArticleData = match item.data {
ItemType::JournalArticle(a) => a,
something_else => todo!("handle wrong type of item"),
}
let title: String = article.title;
(The match could also be written as an if let just as well.)
You could also use pattern matching to go through the entire structure, rather than only the enum which requires it:
match z.get_item(item_id, None).unwrap() {
Item {
data: ItemType::JournalArticle(JournalArticleData {
title,
..
}),
..
} => {
// Use the `title` variable here
},
something_else => todo!("handle wrong type of item"),
}

After switching from a filesystem to mongodb approach, how can I recreate nested directory iteration?

I was storing files in a nested file structure like
data/category/year/month/day/type/subtype/0.json
and to get a list of files / directories within any folder I'd simply use a func like:
getDirectoryContentsSync(pathName) {
let exists = this.exists(pathName);
if (exists) {
let files = fs.readdirSync(pathName)
return files;
} else {
return [];
}
}
Now I'm switching to storing files in mongodb, identifying the files by their original file-path string like:
store(data, path) {
this.db.collection('fs').insertOne({
path,
data
});
}
load(path) {
let data = this.db.collection('fs').find({
path
})[0].data;
return data;
}
But I'm struggling to figure out a way to continue iterating through the structure the way I used to. The approach I'm thinking is pretty gross, like to assign a separate value for each sub-path pointing to children but I think its gonna be a really bad approach, something like:
store(data, path) {
this.db.collection('fs').insertOne({
path,
data
});
let pathParts = path.split("/");
let subPath = "";
pathParts.forEach(dir => {
subPath += dir;
this.db.collection('dir').insertOne({
path: subPath,
data: true,
children: []
});
});
}
That's not the full code for the concept because I realized it seemed like an overly complicated way to do it and decided to stop and ask. I'm just new to mongo db and I bet there's a much better way to handle this but have no idea where to start. What's a good way to do what I want?

Actionscript Take Input and compare to an Int

I'm trying to take an input from the user using an Input Text field, this data is a number. I want the user to input the correct number (in this case 1) and then print out yay.
However, i can't get it to work. Any help is much appreciated.
I assume the issue is to do with comparing an int and a string, but honestly im not sure anymore.
import flash.events.MouseEvent;
import flash.text.TextField;
var dayVar:String = dayInput.text;
var dayNum:Number = Number(dayVar);
stop();
button3.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler3);
function mouseDownHandler3(event:MouseEvent):void
{
if(dayNum == 1) {
trace("yay");
} else {
trace("nay");
}
}
You will have to update your dayVal and/or dayNum after user has given input. So in this minimal case you can simply:
function mouseDownHandler3(event:MouseEvent):void{
if(Number(dayInput.text)==1) {
trace("yay");
} else {
trace("nay");
}
}
Other possibilites would be listening Event.CHANGE for the text input, or KeyboardEvent to update your variables, but in this case the MouseEvent handler does the job easier.
You can use restriction property for text field input like this:
dayInput.restrict = "0-9";
This should omit to type only digits.

Which algorithm to find the only one duplicate word in a string?

This is very common interview question:
There's a all-english sentence which contains only a duplicate word, for example:
input string: today is a good day is true
output: is
I have an idea:
Read every character from the string, using some hash function to compute the hash value until get a space(' '), then put that hash value in a hash-table.
Repeat Step 1 until the end of the string, if there's duplicate hash-value, then return that word, else return null.
Is that practical?
Your approach is reasonable(actually the best I can think of). Still take into account the fact that a collision may appear. Even if the hashes are the same, compare the words.
It would work, but you can make your life a lot easier.
Are you bound to a specific programming language?
If you code in c# for example, i would suggest you use the
String.Split function (and split by " ") to transform your sentence into a list of words. Then you can easily find duplicates by using LINQ (see How to get duplicate items from a list using LINQ?) or by iterating through your list.
You can use the Map() function, and also return how many times the duplicate word is found in the string.
var a = 'sometimes I feel clever and sometimes not';
var findDuplicateWord = a => {
var map = new Map();
a = a.split(' ');
a.forEach(e => {
if (map.has(e)) {
let count = map.get(e);
map.set(e, count + 1);
} else {
map.set(e, 1);
}
});
let dupe = [];
let hasDupe = false;
map.forEach((value, key) => {
if (value > 1) {
hasDupe = true;
dupe.push(key, value);
}
});
console.log(dupe);
return hasDupe;
};
findDuplicateWord(a);
//output
/* Native Browser JavaScript
[ 'sometimes', 2 ]
=> true */

Actionscript deserialize Strings into objects

is there a way to deserialize strings to objects in actionscript:
i.e.
var str:String = "{ id: 1, value: ['a', 500] }";
should be made into an appropriate actionscript object.
this is not json, since the keys are not wrapped in quotes.
Ok, for that type of data pattern, there's not a nice way that I know of to do this. going off the assumption you can't affect the data to make it more JSON-like ... here's off the top of my head what I would conceptually try:
var str:String = "{ id:1, value:['a', 500] }";
// strip off the { and } characters since we've nothing nice to do that for us...
var mynewString:String = str.slice(1, str.length - 1);
var stringItems:Array = mynewString.split(",");
var obj:Object = new Object();
for (var i in stringItems)
{
var objProps:Array = stringItems[i].split(":");
// kill off the quotes here
obj[props[0]] = objProps[1].slice(1, objProps[1].length - 1);
if ( obj[props[0]].indexOf('[') == 0 ) {
// remove [ and ] if there
var maybeStrArray:String = obj[props[0]].slice(1, str.length - 1);
// right now assume we're an array based on our inbound data
var strArr:Array = maybeStrArray.split(",");
obj[props[0]] = strArr;
}
}
Something like that or similar to it anyway. Yes, it's crude, and absolutely it could be fashioned in a way that is more flexible (such as move the string to array convert to its own function so I could use it elsewhere). It's just the first thing that conceptually came to mind as an answer.
Try that, tweak around with it and see if it helps.
You can use as3corelib library for JSON deserialization. It's really not worth spending your time on writing own implementation (except you wish so).

Resources