官术网_书友最值得收藏!

Injection - sorting it out

A first example of passing functions as parameters is provided by the Array.prototype.sort() method. If you have an array of strings, and you want to sort it, you can just use something like the following code. For example, to alphabetically sort an array with the colors of the rainbow:

var colors = [
"violet",
"indigo",
"blue",
"green",
"yellow",
"orange",
"red"
];
colors.sort();
console.log(colors);
// ["blue", "green", "indigo", "orange", "red", "violet", "yellow"]

Note that we didn't have to provide any parameters to the .sort() call, but the array got sorted perfectly well. By default, this method sorts strings according to their ASCII internal representation. So, if you use this method to sort an array of numbers, it will fail, since it will decide that 20 must be between 100 and 3, because 100 precedes 20 --taken as strings!-- and the latter precedes 3... this needs fixing! The code below shows the problem.

var someNumbers = [3, 20, 100];
someNumbers.sort();
console.log(someNumbers);
// [100, 20, 3]

But, let's forget numbers for a while, and keep to sorting strings. We want to ask ourselves: what would happen if we wanted to sort some Spanish words (palabras) -- but following the appropriate locale rules? We would be sorting strings, but results wouldn't be correct, anyhow:

var palabras = ["?andú", "oasis", "mano", "natural", "mítico", "musical"];
palabras.sort();
console.log(palabras);
// ["mano", "musical", "mítico", "natural", "oasis", "?andú"] -- wrong result!

For language or biology buffs, "?andú" in English is "rhea", a running bird somewhat similar to ostriches. There aren't many Spanish words beginning with "?", and we happen to have these birds in my country, Uruguay, so that's the reason for the odd word!

Oops! In Spanish, "?" comes between "n" and "o", but "?andú" got sorted at the end. Also, "mítico" (in English, "mythical"; note the accented "i") should appear between "mano" and "musical", because the tilde should be ignored. The appropriate way of solving this is by providing a comparison function to sort(). In this case, we can use the localeCompare() method:

palabras.sort((a, b) => a.localeCompare(b, "es"));
console.log(palabras);
// ["mano", "mítico", "musical", "natural", "?andú", "oasis"]

The a.localeCompare(b,"es") call compares strings a and b, and returns a negative value if a should precede b, a positive value if a should follow b, and 0 if a and b are the same -- but, according to Spanish ("es") ordering rules. Now things are right! And the code could become clearer by introducing a new function, with an understandable name:

const spanishComparison = (a, b) => a.localeCompare(b, "es");

palabras.sort(spanishComparison);
// sorts the palabras array according to Spanish rules:
// ["mano", "mítico", "musical", "natural", "?andú", "oasis"]

In upcoming chapters we will be discussing how FP lets you write code in a more declarative fashion, producing more understandable code, and this sort of small change helps: readers of the code, when they get to the sort, will immediately deduce what is being done, even if the comment wasn't present.

This way of changing the way the sort() function works by injecting different comparison functions, is actually a case of the Strategy design pattern. We'll be seeing more about this in Chapter 11, Implementing Design Patterns - The Functional Way.

Providing a sort function as a parameter (in a very FP way!) can also help with several other problems, such as:

  • sort() only works with strings. If you want to sort numbers (as we tried to do earlier above) you have to provide a function that will compare numerically. For example, you would write something like myNumbers.sort((a,b) => a-b)
  • If you want to sort objects by a given attribute, you will use a function that compares to it. For example, you could sort people by age with something along the lines of myPeople.sort((a,b) => a.age - b.age)

For more on the localeCompare() possibilities, see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare. You can specify which locale rules to apply, in which order to place upper/lower case letters, whether to ignore punctuation and much more -- but be careful; not all browsers may support the needed extra parameters.

This is a simple example, that you have probably used before -- but it's an FP pattern, after all. Let's move on to an even more common usage of functions as parameters, when you do Ajax calls.

主站蜘蛛池模板: 子长县| 房产| 宁武县| 南华县| 清涧县| 漾濞| 南澳县| 新巴尔虎左旗| 平原县| 云浮市| 蓝山县| 曲阜市| 五台县| 镇康县| 姜堰市| 衢州市| 汉中市| 泸水县| 平凉市| 梓潼县| 白银市| 高要市| 大城县| 宜昌市| 调兵山市| 磐安县| 玉龙| 玉田县| 宽城| 长宁区| 万荣县| 政和县| 郑州市| 友谊县| 宁陵县| 社旗县| 康乐县| 桂林市| 丰镇市| 夏邑县| 安阳市|