In the 1.3 release of FunctionFlip, I added an About box that shows the current version number. In the spirit of DRY, I didn’t want to hardcode the version number, as I’m likely to forget to change it in a future release. Since the information already exists in the bundle’s Info.plist file, I should treat that as the authoritative source. How could I get that information into my UI? Cocoa Bindings to the rescue!

The final result
Cocoa’s Display Bindings
First, I added an NSTextField to the About window in the project’s NIB. Thanks to the wonder that is Cocoa-plus-Interface-Builder, I can edit all of the field’s bindings directly from the IB Inspector. The binding of interest is “Display Pattern Value1”, in the “Value With Pattern” category. As explained in Apple’s docs this binding creates complex text from one or more bound values.

The bindings inspector
In my situation, I want to display the text “You’re using FunctionFlip x.y”, with x.y replaced with the version number. The binding uses a special form for the text you want replaced:
%{value1}@ (or
value2, etc.). So I set the Display Pattern value to “You’re using FunctionFlip %{value1}@”. Next, I bind the value to the text I want to appear; in this case, the
bundleVersionNumber key of the window’s controller.
Providing the Version Number
Of course, the window controller doesn’t (yet) provide bundleVersionNumber. Since this is a read-only key, all I have to do is provide - (NSString *)bundleVersionNumber (line breaks marked \):
- (NSString *)bundleVersionNumber {
return [[[NSBundle bundleWithIdentifier:\
FF_PREFPANE_BUNDLE_IDENTIFIER] infoDictionary]\
valueForKey:@"CFBundleVersion"];
}
NSBundle’s infoDictionary method provides the contents of Info.plist as an NSDictionary. Then it’s just a matter of extracting the CFBundleVersion key, which holds the version number.
So that’s all there is to it—-the tight integration within the Cocoa API not only make the version number from Info.plist available in my code, but I can drop it into my UI with little code.
Posted by Kevin Gessner on Mon, 13 Oct 2008
tags: cocoa, bindings
PHP solution to this brain teaser – it only took a few minutes.
In:
$array = array('a', 'b', 'c', 'c', 'd','e', 'e',
'e', 'e', 'e', 'f', 'e', 'f', 'e',
'f', 'a', 'a', 'a', 'f', 'f', 'f');
Out:
abccdee<span>eee</span>fefefaa<span>a</span>ff<span>f</span>
My Solution:
$curr = '';
$count = 0;
foreach($array AS $letter) {
if($curr != $letter) {
if($count > 2) // more than two dupes
print '</span>';
$count = 0;
$curr = $letter;
}
if($count == 2) print '<span>';
$count++;
print $letter . ' ';
}
Posted by Kevin Gessner on Wed, 17 Sep 2008
tags: php
PHP provides two different functions for checking array membership: in_array and array_search.
$array = array('abc', 'def', 'ghi');
in_array('abc', $array); // true
in_array('123', $array); // false
I present a faster technique for checking array membership. PHP’s array type is an associative array; that is, keys can be strings or arbitrary integers, rather than strictly ordered indices. Plus, it’s optimized for fast key lookups. PHP’s library provides a function that transposes keys and values in an array, array_flip . With this function, we can convert our array search for values into a key lookup:
$array = array('abc', 'def', 'ghi');
$flip = array_flip($array);
isset($flip['abc']); // true
isset($flip['123']); // false
A benchmark of 10,000 iterations of finding a value in a 1,000 element array:
| Technique |
Time (s) |
% Time |
Notes |
| array_search (Strict) |
0.0936079025269 |
2.97% |
| array_search (Loose) |
0.187884092331 |
5.96% |
| in_array (Strict) |
0.0828459262848 |
2.63% |
| in_array (Loose) |
0.183130979538 |
5.81% |
| array_flip (naive) |
1.13642597198 |
36.05% |
See below |
| array_flip (smart) |
0.0022439956665 |
0.07% |
| foreach |
1.46642112732 |
46.51% |
Download sample code and benchmark (requires PEAR::Benchmark)
A few caveats:
- Array keys can only be strings or integers, so arrays of other types cannot take advantage of this technique.
- If you’re only going to be checking for a small number of values, the cost of flipping the array will probably outweigh the benefits (see the “naive” case for array_flip).
- Comparison is not strict ; i.e. it’s equivalent to “==” not “===”.
Posted by Kevin Gessner on Sun, 24 Aug 2008
tags: php, array