Monday 22 October 2012

Find the min and max value of a javascript array

Problem:

I'd like to quickly find the minimum and maximum values stored in a javascript array without having kept track of them in advance, and without using a loop.

Solution:

One of the easiest ways to do this is to use Function.prototype.apply with Math.min and Math.max, e.g.

var min = Math.min.apply(null, myArrOfNumbers);
var max = Math.max.apply(null, myArrOfNumbers);

Notes:

When expanded, note that the first of the above examples is roughly equivalent to Math.min(myArrOfNumbers[0], myArrOfNumbers[1], ...). With that in mind, it should be cautioned that the solution in this post should only be used with small arrays, as many javascript engines have a limit as to how many arguments a function can accept, leading to unpredictable behaviour when this limit is exceeded.

For those interested, see more details in the following linked reference for javascript's Function.prototype.apply.

Reference:

Friday 12 October 2012

Icon missing when uploading PhoneGap app to Apple

Problem:

When I upload my Cordova app to Apple for review, I get the following error:
Invalid Image Path - No image found at the path referenced under key "CFBundleIcons": icon-72@2x.png

Solution:

This error seems to be caused because a reference to icon-72@2x.png is present in the icon list of your Cordova XCode project, however the icon has not been added to the project itself by the script that created the project.

To add this icon, simply open your project in XCode, find (or add) the icon to the Resources->icons folder of your project, then drag-and-drop this into the appropriate spot in your XCode project. Note that this icon needs to be 114x114 pixels.

Here are example screenshots of the icon-72@2x.png missing, and adding this icon to your Cordova XCode project. Hopefully someone out there finds these useful :)

Notice that the icon is missing ...

Drag-and-dropping the icon into the project.

Notes:

An alternative solution to this problem is to remove the reference to the image in the icon list. However, it may be useful to render this icon and add it to your project nonetheless. This bug was found and tested in PhoneGap/Cordova 2.0.0 using XCode 3.5. The original project itself was upgraded from an earlier PhoneGap 1.5.0 project.

Reference:

https://groups.google.com/forum/?fromgroups=#!topic/phonegap/51CYGyjj_pU
(Being relatively new to XCode, I wasn't exactly sure how to follow the brief instructions at the above link at first, which is why I created this how-to in order to help out others in a similar situation.)

Saturday 6 October 2012

Replace every instance of a word in a string with a word stored in a variable using javascript

Problem:

In javascript, I'd like to replace every instance of a word (or substring) in a longer string, with a string stored in a variable.

For example, if I had the following string:

The red strawberries fell off the red table.

And I wanted to replace the word "red" with "dark red", the result should be:

The dark red strawberries fell off the dark red table.

However, I'd like to substitute "dark red" with any arbitrary string stored in a variable.

Solution:

One of the simplest ways to do this is to use the regular expression constructor combined with the 'replace' function. The easiest way to show this is by an example:

var replaceThis = "red";
var replaceWith = "dark red";
var theString = "The red strawberries fell off the red table.";

var theNewString =
  theString.replace(new RegExp(replaceThis, "g"), replaceWith);

More details:

Using the 'replace' function is a simple way to replace something in a string. Unfortunately, if you want to replace more than one instance of a substring in a string, passing two strings as parameters to the 'replace' function, such as in "str.replace('this', 'that')", will not work because the function will simply replace only the first match. In the highlighted example above, only the first instance of 'red' would have been replaced with 'dark red'. To get around this issue, the first parameter should be a regular expression, with the desired search string being 'red' and the modifier being 'g' for global matching. In javascript, this regular expression would look like: /red/g

However, regular expressions cannot be passed simply as strings, therefore passing "/red/g" or a variable containing that string as the first parameter of replace would have been interpreted as the string "/red/g" rather than the regular expression /red/g. This problem is worked around by converting the string of the regular expression to a valid regular expression via the regular expression constructor.

Additional details can be found at the following references: