How to use NSPredicate with NSPredicateEditor on different data (Multiple Predicates?) - arrays

I've got an array of filepaths and I've got a NSPredicateEditor setup in my UI where the user can combine a NSPredicate to find a file. He should be able to filter by name, type, size and date.
There are several problems I have now:
I can only get one predicate object from the editor. When I use
"predicateForRow:" it returns (null)
If the user wants to filter the file by name AND size or date, I
can't just use this predicate on my array anymore because those
information are not contained in it
Can I split up a predicate into different predicates without
converting it into a NSString object, then search for every #" OR " |
#" AND " and seperating the components into an array and then
converting every NSString into a new predicate?
In the NSPredicateEditor settings I've some options for the "left Expression":
Keypaths, Constant Values, Strings, Integer Numbers, Floating Point Numbers and Dates. I want to display a dropdown menu to the user with "name", "type", "date", "size". But then the generated predicate automatically looks like this:
"name" MATCHES[c] "nameTest" OR "type" MATCHES[c] "jpg" OR size == 100
Because the array is filled with strings, a search for "name", "type" etc. and those strings do not respond to #"myString"*.name*m the filter always returns 0 objects. Is there a way to show the Name, Type, Size and Date in the Menu, but write "self" into the predicate without doing it by hand?
I've already searched in the official Apple tutorials, on Stackoverflow, Google, and even Youtube to find a clue. This problem troubles me for almost one week now. Thanks for you time! If you need more information please let me know!

You have come to the right place! :)
I can only get one predicate object from the editor.
Correct. It is an NSPredicateEditor, not an NSPredicatesEditor. ;)
When I use "predicateForRow:" it returns (null)
I'm not sure I would use that method. My general rule of thumb is to largely ignore that NSPredicateEditor is a subclass of NSRuleEditor, mainly because it's such a highly specialized subclass that many of the superclass methods don't make that much sense on a predicate editor (like all the stuff about criteria, row selection, etc). It's possible that they're somehow relevant, but if they are, I haven't figured out how yet.
To get the predicate from the editor, you do:
NSPredicate *predicate = [myPredicateEditor objectValue];
If the user wants to filter the file by name AND size or date
You mean (name = [something]) AND (size = [something] OR date = [something])?
If so, NSPredicateEditor can do that if you've set the nesting mode to "Compound".
I can't just use this predicate on my array anymore because those information are not contained in it
What information do you need?
Can I split up a predicate into different predicates without converting it into a NSString object, then search for every #" OR " | #" AND " and seperating the components into an array and then converting every NSString into a new predicate?
Yes, but that is a BAD idea. It's bad because NSPredicate already contains all the information you need, and converting it to a different format and doing string manipulations just isn't necessary and can potentially lead to complications (like if someone can type in a value for "name", what happens if they type in " OR "?).
I'm having a hard time trying to figure out what it is you're trying to do. It sounds like you have an array of NSString objects that you want to filter based on a predicate that the user creates? If so, then what do these name, date, and size key paths mean? What are you trying to do?

Related

How to compare numeric in PostgreSQL JSONB

I ran into strange situation working with jsonb type.
Expected behavior
Using short jsonb structure:
{"price": 99.99}
I wrote query like this:
SELECT * FROM table t WHERE t.data->price > 90.90
And it fail with error operator does not exist: jsonb > numeric the same as text (->>) operator does not exist: text > numeric
Then I wrote comparison as mentioned in many resources:
SELECT * FROM table t WHERE (t.data->>price)::NUMERIC > 90.90
And it's works as expected.
What's strange:
SELECT * FROM table t WHERE t.data->price > '90.90';
a little weird but query above works right.
EXPLAIN: Filter: ((data -> 'price'::text) > '90.90'::jsonb)
But if I change jsonb value to text as: {"price": "99.99"}
there is no result any more - empty.
Question: How actually PostgreSQL compare numeric data and what preferable way to do this kind of comparison.
But you aren't comparing numeric data, are you.
I can see that you think price contains a number, but it doesn't. It contains a JSON value. That might be a number, or it might be text, or an array, or an object, or an object containing arrays of objects containing...
You might say "but the key is called 'price' of course it is a number" but that's no use to PostgreSQL, particularly if I come along and sneakily insert an object containing arrays of objects containing...1
So - if you want a number to compare to you need convert it to a number (t.data->>price)::NUMERIC or convert your target value to JSON and let PostgreSQL do a JSON-based comparison (which might do what you want, it might not - I don't know what the exact rules are for JSON).
1 And that's exactly the sort of thing I would do, even though it is Christmas. I'm a bad person.

nested if statment with so many text conditions ERROR

this is my data table
I'm writing this formula in openoffice not excel, that's why you will see ";" instead of ","
my questions is that I'm trying to put the currency of each country's capital name, and I did it but the thing is that I'm unable to make more than 42 conditions!!!!!
Is there another way or another formula can I use???
Here is the formula I did, and it's working
=IF(D3="AMSTERDAM";"EUR";IF(D3="FRANKFURT";"EUR";IF(D3="OSLO";"NOK";IF(D3="COPENHAGEN";"MULTI";IF(D3="ALICANTE";"EUR";IF(D3="BARCELONA";"EUR";IF(D3="BERLIN TXL";"EUR";IF(D3="VILNIUS";"EUR";IF(D3="BRUSSELS";"EUR";IF(D3="CATANIA";"EUR";IF(D3="DUSSELDORF";"EUR";IF(D3="FARO";"EUR";IF(D3="GRAN CANARIA";"EUR";IF(D3="HELSINKI";"EUR";IF(D3="MALAGA";"EUR";IF(D3="MUNICH";"EUR";IF(D3="PARIS CDG";"EUR";IF(D3="RIGA";"EUR";IF(D3="SANTA CRUZ PALMA";"EUR";IF(D3="SEVILLA";"EUR";IF(D3="TENERIFE";"EUR";IF(D3="BUDAPEST";"HUF";IF(D3="ANTALYA";"TRY";IF(D3="GAZIPASA";"TRY";IF(D3="ISTANBUL";"TRY";IF(D3="BERGEN";"NOK";IF(D3="STAVANGER";"NOK";IF(D3="STAVANGER VIA ESBJERG";"NOK";IF(D3="LONDON CITY";"GBP";IF(D3="LONDON LHR";"GBP";IF(D3="LONDON STN";"GBP";IF(D3="MANCHESTER";"GBP";IF(D3="FUERTEVENTURA";"ISK";IF(D3="LANZAROTE";"ISK";IF(D3="PORTO SANTO";"ISK";IF(D3="GLASGOW";"SCP";IF(D3="GDANSK";"PLN";IF(D3="CLUJ­NAPOCA";"RON";IF(D3="STOCKHOLM";"SEK";IF(D3="PRAGUE";"CZK";""))))))))))))))))))))))))))))))))))))))))
I'd suggest you use a table in another section of your spreadsheet then use VLOOKUP to match the currency to your country.
=VLOOKUP(D3;Currency_Table;2;FALSE}
Which is lookup D3 in the table named Currency_Table and return the exact match (from FALSE) in the second column which will give you your currency.
Or if you want the formula to exist without dependency upon another table you could use something like:
=VLOOKUP(D3;{"AMSTERDAM"\,"EUR";"FRANKFURT"\,"EUR";"OSLO"\,"NOK"; etc...};2;FALSE}
NB: I've added an escape \ before the comma because I'm assuming you are from a language area that uses , as a decimal by your language settings I'm assuming you'll need that in your array for that to work.

Using text in a column of Date/Time type in access

I have a column in MS Access in which the data could be any of the following:
A date
Text string: "n/a"
Text string: "n/e"
The vast majority of entries will be dates but a very few will need to be these specified text strings. I would like to still be able to perform date calculations on the column. Whats the best datatype to use?
In my opinion the best approach would be to leave the date field as Date/Time and then add another field to indicate the status if the Date/Time field is Null. Something like:
DateField DateStatus
--------- ----------
2014-09-21
n/a
2014-09-23
2014-09-25
n/e
You could use a single Text field, but then any time you wanted to use the field value as a proper Date/Time value you'd have to convert it using CDate(). You would also have the possibility of other junk getting in there, or dates getting entered in different formats (e.g. d/m/yyyy vs. m/d/yyyy). And finally, you would lose the ability to easily determine whether a Date/Time value is in a particular row (which in my approach would simply be ... WHERE DateField IS [NOT] NULL).
I agree with Gord Thompson's answer - mainly because it's so non-intuitive to have, essentially, two completely different types of data in a single column, and because it's going to make validation/data integrity stuff so much harder with little upside - and, as he indicates with the CDate() reference, dates basically only work reliably like dates if they're in a "date/time" field. Microsoft has a page on choosing a data type that explains some of the Access-specific differences in more detail.
I also suggest that you don't actually have a text field for those "comments," since you say there's only a handful of potential options - use a Long Integer and connect back to a separate table with the list of allowable entries. This will allow you to run reports more easily, change the "display text" in one step instead of potentially dozens of times, etc. It also saves a relatively small amount of space per record (long integer = 4 bytes; text = up to 255 bytes.)
You can also do fun data/reporting stuff with that Comment (long integer) field and dates - even combined into ranges, by the way - queries let you use the two different columns to create a single answer. I have a report that's grouped so that you can see stats for everything that's active (by quarter in which they start) plus everything that's pending (with the code indicating who's responsible for watching this record,) plus everything that's not pending but still doesn't have a start date (with the reason code displayed,) plus everything that's expired (by quarter in which they ended.) It looks like each of those things is in a single column in the report, but it's actually like five columns that have been concatenated with the IIf function.
(Almost every argument I can come up with boils down to "this is what relational databases are all about and why they're so awesome.)

VB.Net - Excel application get showing values of an range

I'm trying get an Excel Range and copy into an array of objects with Vb.Net.
This is not a problem. I use the following code:
Dim vValues(,) As Object = ExcelApp.Range(vRange).Value
And works fine; but I have a the following case:
In the column "C"; the value has a specific format and internally has another value.
My question is:
Somebody know the way to get the information exact as the user see?
I'm trying to get the information without use a For ... Each or some kind of cycle.
I'm also tried to avoid use "text to columns" function.
Both seems right solutions, but would impact the performance with a lot of data.
FYI: Also I can get the information through the ODBC connection; but I'm searching the solution using a Range
Exactly what the user sees is the Text property. But you cannot have an array of that, you will have to query each cell individually.
You are getting a Double value in your array instead of a DateTime value because you have "Time" formatting applied in Excel. If you had a format from the "Date" category, Excel would instead send a proper Variant/Date, not a Double that represents it.
Another option would be constructing the DateTime objects on the .NET side, provided you know in which columns they should be.

advice for transforming data gathered from screen scrapers

good day folks,
I have my screen scraper (scrapy) collecting data of property listings on several property websites. They all have several common fields like price, floor area etc. However, like all scraped data, the values for the fields are rather undesirable right now. For instance, in price, I have obvious values like $1,000,000,000, but I also have stuff like $1,000,000,000 Price on Ask and Price on Ask. So currently, I stored all my scraped fields as char in my database.
I would like to transform these string fields in my database from characters to the appropriate type e.g string to int, so I can index them accordingly. Can someone offer me some advice what would be sensible procedure and method to begin transforming the data?
You want to throw away the "Price On Ask" string? Or is that valuable information?
If there is a lot of noise in the data, and it is all of no-interest, I'd run a filter to remove all non-digits.
But, if time allows, I prefer to process the data explicitly with pattern matching (sample code is PHP):
//$price is raw string
$price=str_replace(',','',$price); //Get rid of commas
$price=str_replace('$','',$price); //Get rid of dollar signs
if($price=='Price On Ask')$price=null;
elseif(preg_match('/^\d+$/',$price))$price=(int)$price; //Simple number
elseif(preg_match('/^(\d+) Price On Ask$/i',$price,$parts)){
$price=(int)$parts[1];
}
else{
echo "Unexpected price string: $price\n";
$price=null;
}
I then have the structure to set flags for some of the strings. Also, when a new string appears in the data my script gets noisy and I can decide if it matters or not.
(Note: setting $price to null implies putting a NULL in the database, not a zero.)

Resources