Using jQuery.map() to Map One Object To Another
Today was another day of learning. As part of a redesign, I had to convert a JavaScript object to an array used in the jQueryUI autocomplete plug-in. I have a service that returns a JSON object containing a list of category ID and Names that match a search for terms entered into an auto complete text box. I need to convert this to an array of arrays containing the category’s ID, Name, and the term highlighted in the Name. If you have a problem like this, here’s one way to solve it.
Before I jumped into the chaotic world of loops and recursive algorithms, I decided to see if there was something new and simple. Just so happens jQuery 1.6 has a revamped $.map function that can provide exactly what I need. Last time I used map it only worked on arrays, but now it can take a JavaScript object…sweet.
It’s so simple it should be a crime. You just feed it your object and a callback function and it returns the result of the callback function in an array. So as it iterates through each item in your object, it runs the anonymous function against the item and packages the results into an array. When it’s done it returns the array to you. No loops, no iterators, 3 lines of code and done son. Did I say I love jQuery.
Here’s what I have:
Alert: this is not production ready code nor does it provide a best practice guidance or implementation.
$.map(categories, function(item) {
var highlight = item.Title.replace(/(+request.term+)/,'i'),'<span class=\"autofound\">$1</span>');
return { id: item.Id, highlight: highlight, name: item.Title };
}
First I pass the map function a collection of categories and supply the anonymous function callback function(item){…}. To set the highlighted term we are using RegEx to find the requested term in the current category item in the map iteration. request.term is the term that the user typed into auto complete, as they type the map function is called and will return the categories that match the request.term in an array with the id, name, and a highlight comprised of the category Title with the requet.term bolded in the category’s Title. To widen the RegEx matche, we are also ignoring case (‘i’). Once the term is found we replace it with itself, but bolded. For example: if term is Hello and item’s category is “Hello World”, this returns “Hello World” as the highlight. Note: you can add another argument to the anonymous function as an iterator index (e.g. function(item, i) with i providing the index in the iteration, actually the index or key of the current item (you can check the references below for more info on this).
You may ask why I don’t write a loop or use jQuery .each(). There is most likely a better way, there always is. Why do it this way? The real answer is because .map() is new (upgraded) and cool and I wanted to learn how to use it with objects. The correct answer should be that it performs better or solves some other issue that the other options don’t. I can’t say that with certainty. I do remember reading posts about comparisons and I know the quick logic in my head decided just to use .map() in this situation (which isn’t a production use, but a proof of concept spike), but it’s been a few days since I did my research and I don’t remember pros and cons, nor do I have time to look again. So, I will leave that research to you and Google. Try http://tinyurl.com/6fdxa8a for a start.
Some of the references that I can remember using included:
- http://api.jquery.com/jQuery.map/ – official jQuery.map() API doc
- http://www.learningjquery.com/2011/05/jquery-map-in-16 – actually has a deep look into .map() and .each()
- http://www.javascriptkit.com/javatutors/re3.shtml – not related to .map(), but a quick glance to get my RegEx ignore case property
- http://www.michelsalib.com/2010/08/extended-customization-of-jquery-ui-autocomplete/ – actually came across this after my spike. I guess I duplicated someone else’s solution. Either I saw this before or I can feel better about the approach because someone else came to the same conclusion. Either way he has a good post on it.
View more posts in:
jQuery


Leave a Reply