Servoy Tutorial: The Mighty Array

Servoy Tutorial Photo Credit: polamance via Compfight

Servoy Tutorial Photo Credit: polamance via Compfight

This is a Servoy Tutorial on how to use some of the more advanced Javascript array functions. In previous Servoy Tutorials, we talked a lot about objects and object-oriented programming , but I wanted to make sure you understood the full power of the array and its functions as well. Without a deep understanding of how some of the more advanced array functions work, your not properly equipped for your journey to Servoy Nirvana. Solving coding challenges with efficiency and brilliance is the destination, and without a full understanding of array functions, you can not achieve it. Some of the things covered here you may already be familiar with, and some of them, I bet, will humble you.

A Javascript array is an object, and can be created two ways, either using the constructor, or as a literal. The literal is the preferred way and the approach that will be used throughout this Servoy tutorial.

If you select the Array node under JSLib in your Servoy Developer Solution Explorer view, you will see a lot of methods that you can use with an array, along with two properties, index and length. You probably know how to use index and length, so I am not going to bore you by teaching basic Javascript here. In this Servoy tutorial, I am going to focus on some key methods of the array prototype and demonstrate some of their uses. Hopefully, you will learn a trick or two.

.concat(), .join()

The array .concat() method is normally used to join two arrays together, like this:

So, what if you want to make a copy of an array? You can’t do this by assigning one array equal to another array, because that makes them the same array, meaning what affects the one array also affects the other (they are the same object).

Similarly, writing a function that loops through the first array and pushes onto a new array, works, but is totally lame.

The most efficient way to do copy one array into a new array is to simply use .concat() without passing it any parameters. This makes a shallow copy of the original array, returning a new one. A shallow copy means that the new array still has a reference to the elements, but is not the same object as the original.

I will just mention that array .concat() is often confused with .join(). The difference is that .join(separator) takes an array with elements and combines them into a string, separated using the provided separator, or defaulting to “,” as the separator. It cannot be used to join two arrays together, or make a shallow copy of an array.

.filter()

I want to talk about a few things before we actually get into how .filter() works, and how you should use it. Arrays can store pretty much anything as elements;, strings, numbers, JSRecord, JSFoundSet, JSDataSet, objects, and even other arrays.

You can store simple information in an array, like strings (bet you knew this!):

You can store more complex data in an array, like additional arrays (you probably knew this):

You can store complex information in an array using a key, in what is know as as an associated array (you might have know this):

Associated arrays are kind of cool, because you can check the array, by key, to see if the data is already there. For example, perhaps you are looping through data and you need to store information about each unique occurrence of a particular data type. You can build an associated array doing something like this:

One of the problems in using an associated array, is that if you wanted to store more information for each of the keys, like rRec.total_amount, rRec.status, etc., you would have to store an array of information as each element, and remember the mapping of the data. It would look something like this:

Okay, now that we have that all out of the way, we can learn about how to do things more elegantly, using the array .filter() method. To demonstrate the power of the filter we are going to use objects as the elements in our array. Suppose we wanted to extract all the objects whose “role” property is set to “Manager”, and put them in a new array. A common way of doing that would be to loop through the objects in the array and read the role property, then push the object onto our new array.

A more elegant and efficient way to do this is to use the array .filter() method, which accepts a callback function that returns true or false. In that callback function we examine each element in the array individually. Here is an example of how to extract the objects with “role === ‘Developer’”.

In addition to the callback function, the array .filter() method provides the callback function access to the index and original array, like this:

Finally, just because you need to know this, if you truly want to write awesome code, you can chain functions together, and .filter() the objects, extract specific data from the object using the .map() function, and then use the .sort() function to sort the result, achieving coding excellence in one awesome line of code. We will learn more about .map() and .sort() in a bit, so stick with it.

Ah…, .filter(), one of my favorites. Put this one in your toolbox; its essential for your journey to greatness.

.every(), .some()

Using .some() allows you to loop through the elements in the array using a callback function, until it finds one where the callback returns true. As soon as the callback function finds the first element that satisfies the condition, it exists. The callback is passed the element, the index and the original array. An optional second argument can be passed giving you the context “this” within the callback. The .every() method works the same way, but with the every() method, callback returns on false, rather than true.

.forEach()

The .forEach() iteration method allows you to loop through each of the elements in the array using a callback which is passed the element, the index and the original array. An optional second argument can be passed giving you the context “this” within the callback.

.indexOf(), lastIndexOf()

The .indexOf() method looks up array element positions and returns -1 if not found. A second argument can provide the start index for the search start. If you want to search the other way, use .lastIndexOf(). You probably know by now how to use these two, but did you know that you could do the following?

.map()

The .map() method is a powerful iteration method and can be useful in several scenarios. The callback function is called once for each element in the array which constructs a new array from the callback.

I have found .map() useful for building objects from arrays of data.

Also, as we saw earlier in the .filter() example, we can use .map() to access properties inside objects that are stored as elements in an array.

.pop(), .push(), .shift(), .unshift()

You should already know how to use these four methods (if not, go learn them, they are basic requirements). I don’t have much to say about these but I wanted to make certain you know that you can push more than one element at a time.

.reverse()

I will leave this one to your imagination.

.slice()

I’m sure most of you have used the .slice() method before, but did you know it can be used for two purposes? The most common use is to remove a small subset of an array and return a new array.

Did you know, however, that like .concat(), the .slice() method without any arguments can be used to shallow copy an array?

.sort()

Okay, I bet we all think we know how to use the array .sort() method, but maybe I should just review them anyways?

Here is how to sort a numeric array in ascending order.

Here is how to sort a numeric array in descending order.

Here is how to randomize the array elements, which is quite often necessary for scheduling apps and other situations.

Here is how to sort an array of objects, both ascending and descending, using a specific key (in this case “first”). If you are going to work with objects, you need to know these two methods. Clip the snipets and add them to your utils library.

The last one, you have seen before when we did .filter(). Here it is again, using the array of objects defined above.

.splice()

I haven’t seen too many people use the .splice() method, even when they could have. It’s very powerful, allowing you to replace existing values in an array with new ones, in the exact same positions. You specify the start position, the number of elements to replace, and provide the elements that will replace the existing data.

.dotzSortTwoArrays()

Okay, you got me, there is no such array method. Actually, its my own method that I wrote to sort two arrays in ascending order, using the first array as the ascending order. I have often used this when two arrays have related data at the same index locations, and I need to sort them and maintain the integrity of the related indexes.

Here is how you would use the method.

Conclusion

Whew! That was a lot, and if you stuck it through to the end, congratulations! Although it may seem to be a dry and boring topic, I don’t think you can truly get a mastery over Servoy, without fully understanding the basic nuances of the Javascript language. Arrays are as important as objects to master, and together, they will take your code to the next level. I appreciate you taking the time to work through this Servoy tutorial with me. I hope it made sense and you learned a thing or two.  Now go out there and put these array methods to good use!

That concludes this Servoy tutorial. I hope you enjoyed it.

 

Gary Dotzlaw
Gary Dotzlaw has 20+ years of experience as a professional software developer and has worked with over 100 companies throughout the USA and Canada. Gary has extensive qualifications in all facets of the project life cycle, including initial feasibility analysis, conceptual design, technical design, development, implementation and deployment. Gary is an expert Servoy Developer, with extensive large-commercial project experience, and has written numerous advanced tutorials on Servoy development.