Útkeresés a .Map () segítségével

A megoldás részletességét és eleganciáját azok az eszközök vezérlik, amelyekkel egy adott problémát meg kell oldanunk. Míg a problémamegoldás célja egy probléma megoldása , a módszereknek a lehető legelegánsabb módszer felé kell haladniuk. Az ilyen megoldás felé vezető út azonban aszimptotikus görbén fekszik. A tökéletesség egyre közelebb kerül, de örökre elérhetetlen marad.

A probléma

Képzelje el, hogy van tömbje, és meg kell változtatnia a tömb minden elemét. Talán például egy magasságtömböt hüvelykben megadva és centiméterre kell átalakítania. Vagy esetleg átalakíthat egy Celsius-hőmérsékleti tömböt Fahrenheit-re. Ha még nem ismeri a programozást, az elméje azonnal áttérhet a hurok valamilyen formájára. És képzeld csak? Biztos vagyok benne, hogy sikerülne működni.

Azonban én itt, hogy egy olyan eszköz - valamit, hogy ha csak egy kicsit közelebb elegáns: Array.prototype.map().

A mapmódszer lehetővé teszi számunkra, hogy egy tömb minden elemét átalakítsuk, az eredeti tömb befolyásolása nélkül. Ez tekinthető a magasabb rendű függvény és a funkcionális programozási technika, mert tart a függvény argumentumként, és mi számításának elvégzésére anélkül mutálódik az állam a mi alkalmazás.

Mapa tömb prototípusától örökölt tulajdonság. A prototípusok beépített módszereket biztosítanak az objektumokhoz (a tömbök speciális objektumtípusok a JavaScript szemében). Bár maplehet, hogy kicsit idegenebb, ez a prototípus nem különbözik például a Array.lengthprototípustól. Ezek egyszerűen JavaScript-be süllyesztett módszerek. A tömb prototípusokat hozzáadhatja és mutálhatja: Array.prototype.= ...

A lecke végére felfedezzük, hogyan mapműködik, és megírjuk saját tömb prototípus módszerünket.

Tehát mit csinál a .map ()?

Tegyük fel, hogy Celsius-tartományban van egy tömb hőmérséklet, amelyet Fahrenheit-re szeretne váltani.

A probléma megoldásának számos módja van. Ennek egyik módja lehet egy forhurok megírása, amellyel létre lehet hozni egy Fahrenheit-hőmérséklet tömböt az adott Celsius-hőmérsékletekbõl.

A forhurokkal azt írhatjuk:

const celciusTemps = [22, 36, 71, 54]; const getFahrenheitTemps = (function(temp) { const fahrenheitTemps = []; for (let i = 0; i < celciusTemps.length; i += 1) { temp = celciusTemps[i] * (9/5) + 32 fahrenheitTemps.push(temp); } console.log(fahrenheitTemps); [71.6, 96.8, 159.8, 129.2 })();

Néhány megjegyzendő dolog:

  1. Működik.
  2. Azonnal meghívott függvény kifejezést (IIFE) használjuk, hogy elkerüljük a függvény meghívását is.
  3. Kicsit bőbeszédű és nem túl elegáns.

Map lehetővé teszi számunkra, hogy a fenti kódot átvigyük és átalakítsuk a következőkre:

const fahrenheitTemps = celciusTemps.map(e => e * (9/5) + 32); console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]

Tehát hogyan működik a térkép?

Mapvesz egy függvényt és alkalmazza azt a tömb minden elemére. Írhatnánk mapegy kicsit bőbeszédű a ES5 hogy ezt egy kicsit pontosabban.

const fahrenheitTemps = celciusTemps .map(function(elementOfArray) { return elementOfArray * (9/5) + 32; }); console.log(fahrenheitTemps); // [71.6, 96.8, 159.8, 129.2]

Ha a térképfunkciónk meg tudná mondani, hogy mit csinál, akkor azt mondaná:

"A tömb minden eleméhez megszorozom (9/5) -vel, majd hozzáadom a 32.-et. Ha ez megtörtént, az eredményt elküldöm elemként egy új tömbben, fahrenheitTemps néven."

Nézzünk meg egy gyakoribb használati esetet. Tegyük fel, hogy van egy tömb peopleobjektumunk. Minden objektumnak van egy nameés agekulcs-érték pár. Olyan változót akarunk létrehozni, amely csak mindenki neve a tömbben. A forhurok módszerünkkel írhatjuk:

const people = [ {name: Steve, age: 32}, {name: Mary, age: 28}, {name: Bill, age: 41}, ]; const getNames = (function(person) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();

a map:

const names = people.map(e => e.name); console.log(names) // [Steve, Mary, Bill];

Figyeljük meg, hogy itt nem változtatunk semmit, egyszerűen visszaadjuk a kulcs-érték párot name.

A forhurkok ismét működnek. De ez bőbeszédű, és minden alkalommal létre kell hoznunk egy új egyéni függvényt, amikor más átalakítást akarunk végrehajtani. A programozás fő része a DRY kód írása (Ne ismételje meg önmagát). Ezek a magasabb rendű funkciók, például a térkép lehetővé teszi számunkra, hogy kevesebb kódsorban bonyolultabb programozást végezzünk, mint amennyit nélkülük tudnánk.

A kerék újrafeltalálása:

Annak érdekében, hogy jobban megértsük, mi történik a motorháztető alatt, elkészítjük saját térképfunkciónkat, amelyet a tömb prototípusához csatolunk.

Először egy prototípus módszer csatolásához egy tömbhöz írjuk:

Array.prototype.

tehát nekünk:

Array.prototype.myMap =

De mi lesz a kódunk?

A forfenti hurkokból már megvan a szükséges logika . Csak annyit kell tennünk, hogy kissé visszafogjuk. Tegyük át az utolsó függvényt, amelyet írtunk getNames().

Ne feledje, hogy ez a függvény elvett egy személyt (más szóval a tömbünk egyik elemét), egyedi átalakítást hajtott végre az elemre (a forciklussal és valamilyen logikával), és egy névtömböt (vagy egy új tömböt) adott vissza.

const getNames = (function(person) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();

Először változtassuk meg a funkciónk nevét. Végül is ez az új módszer nem feltételezi, hogy tudja, milyen tömböt fog használni:

const myMap = (function(person) { //Changed name const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();

Másodszor, elkészítjük a saját verzióját .map(). Tudjuk, hogy ehhez a felhasználó által biztosított funkcióra lesz szükség. Változtassuk meg a függvényünk által használt paramétert:

// It is a bit verbose, but a very clear parameter name const myMap = (function(userProvidedFunction) { const names = []; for (let i = 0; i < people.length; i += 1) { name = people[i].name; names.push(name); } console.log(names); // [Steve, Mary, Bill]; })();

Végül fogalmunk sincs, hogy ez a módszer milyen tömböt fog működni. Tehát nem hivatkozhatunk people.length, de lehet hivatkozni this.length. this, visszaadja azt a tömböt, amelyre a módszer hat. Tisztítsuk meg néhány egyéb változó nevét is:

const myMap = (function(userProvidedFunction) { // change variable name const newArr = []; // use "this.length" for (let i = 0; i < this.length; i += 1) { // use "this[i]", and change variable name const newElement = this[i]; // update the array we push into newArr.push(newElement); } // Return the newly created array return newArr; })();

We’re almost there, but there is one thing we are forgetting. We haven’t transformed the array! All we’ve done above is return the old array. We have to apply the user-provided function to each element of the array:

const myMap = (function(userProvidedFunction) { const newArr = []; for (let i = 0; i < this.length; i += 1) { /* Transform the element by passing it into the * user-provided function */ const newElement = userProvidedFunction(this[i]); newArr.push(newElement); } return newArr; })();

Finally, we can attach our new function toArray.prototype.

Array.prototype.myMap = myMap;

A final sanity check:

const myArray = [1, 2, 3]; // Multiply each element x 2 const myMappedArray = myArray.myMap(e => e * 2) console.log(myMappedArray) // [2, 4, 6];

Summary

Map is a prototype method offered by arrays. Behind the scenes, it iterates through the array, applying a user-provided function to each element. Ultimately, it returns a new array with the transformed values. It does this without mutating the original array. Because the parameter it takes is a function, it is considered a higher-order function. In addition, its use falls into the functional programming paradigm.

Thanks for reading!

woz