forked from uciharis/dicoding-JS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11-functionalProgramming.js
executable file
·346 lines (312 loc) · 12.7 KB
/
11-functionalProgramming.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*
* ---Functional Programming ---
yang akan dipelajari :
- paradigmna
- konssep pure function, immutability, hi order
- reusable function
functional programming atau disingkat FP didasarkan pada fungsi matematika murni.
FP ditulis dg gaya deklaratif yang berfokus pada "what to solve"
dibanding "how to solve" yang dianut gaya imperatif.
berikut contoh gaya imperatif :
*/
const names = ['harr', 'ron', 'jeff', 'tomas'];
const namesWithExcmark = []; // imperatif karna pengisian berdasarkan array lama
for (let i=0; i< names.length;i++){ //disebut imperatif karna memikirkan perulangan dan prosedurnya alias how
namesWithExcmark.push(`${names[i]}!!`);
}
console.log(namesWithExcmark);
// gaya deklaratif atau FP
const nama = ['heri', 'roon', 'jaff', 'toms'];
const namaWithExcmark = nama.map((nama)=> `${nama}!!`);
console.log(namaWithExcmark);
// gaya deklaratif fokus pada apa yang disolve. tidak perlu memikirkan proses looping, tanpa perlu tau
// kapan looping akan berhenti.
// JS sendiri mendukung paradigma FP. banyak higher func yang dapat dimanfaatkan sbg utilitas,
// contohny adalah fungsi array map()
//ada 4 konsep besar yang ada di FP yaitu pure function, immutability, recursive dan Hi order function
// -- pure function --
// pure funct adalah konsep dari pembuatan fungsi yang mengharuskan fungsi tdk tergantung thd nilai yang
// yang berada di luar fungsi atau parameternya.
// sehingga seperti apa keadaannya fungsi yang dibuat slalu menghasilkan sesuatu yang sama, terkecuali
// fungsi tsb diberikan nilai parameter yang berbeda
//contoh :
let PI = 3.14;
const hitungLuasLingkaran = (jariJari)=> {
return PI*(jariJari * jariJari);
}
console.log(hitungLuasLingkaran(4));
PI = 5; //tidak sengaja inisiasi PI
console.log(hitungLuasLingkaran(4));
// functi diatas bukan pure funct karena nilai PI berubah maka nilai lingkaran berubah.
//berikut contoh pure function yang sebenarnya :
const hitungAreaLingkaran = (jari)=> {
return 3.14 * (jari);
}
console.log(hitungAreaLingkaran(6));
// pure funct selain dilarang bergantung pada nilai luar, dilarang keras juga utk mengubah nilai
// yang berada di luar baik secara sengaja maupun tidak sengaja
// mari kita analisa lagi sbuah funct apakah pure atau tidak
const createPersonAge = (age,person)=> {
person.age = age;
return person;
};
const person = {
name: 'bobo'
};
const newPerson = createPersonAge(18,'jokook');
console.log({
person,
newPerson
});
// fungsi createPersonAge bertujuan utk membuat objek person baru dg tambahan properti age dan objek person
// alih2 membuat objek baru, ia juga malah mengubah nilai dr objek lama.
// hal ini menyebabkan fungsi createPersonAge bukanlah pure funct
// cara mengubahnya adlah dg memanfaatkan destructuring objek
const createPersonUmur = (umur, orang)=>{
return {...orang, umur};
};
const orang = {
nama: 'bobos'
};
const newOrang = createPersonUmur(47, orang);
console.log({orang, newOrang});
// utk memastikan suatu fungsi sudah pure atau belom, pastikan 3 hal berikut pada fungsi yg dibuat
// 1. mengembalikan nilai yg sama bila inputannya sama
// 2. hanya bergantung pada argumen yg diberikan
// 3. tidak menimbulkan efek samping
/** --- Immutability ---
* adalah sebuah objek yg tidak boleh diubah setelah objek tsb dibuat
* konsep immutability sangat kental pada paradigma FP.
* ketika menggunakan array.map(), alih2 mengubah nilai dr array itu sendiri, malah ia membuat atau menghasilkan array baru
*/
const nama1 = ['haria', 'roen', ' jeff', 'tomes'];
const newNama1Excmark = nama1.map((namA)=> `${namA}!!!`);
console.log({
nama1, newNama1Excmark
});
// lantas bagaimana bila kita perlu mengubah nilai dr sebuah objek ? contoh seperti ini
const yuser ={
firstnem : 'herii',
lastnem : 'proter', //ini yg typo
}
const renemLastNemUser = (newLastName, yuser)=> {
yuser.lastnem = newLastName;
}
renemLastNemUser('poter', yuser);
console.log(yuser);
// tujuan tercapai namun ini masih blm konsep FP. seharusnya tidak mengubah nilai objek langsung tetapi
// return nilai dalam objek baru.
const yuser1 = {
firstNem1: 'herri',
lastNem1 : 'proter' //ini yg typo
}
const createUserWithNewLastNem = (newLastNem1, yuser1)=> {
return {... yuser1, lastNem1: newLastNem1};
}
const newYuser= createUserWithNewLastNem('pooter', yuser1);
console.log(newYuser);
// hasilnya sama
// anda juga bs menyesuaikan nama func dari renemLastNemUser menjadi createUserWithNewLastName
// hal ini perlu utk mengindikasikan bahwa fungsi mengembalikan
// atau menghasilkan objek user baru
/* --- Rekursif ---
*
rekursif merupakan teknik pada sebuah fuct yang memanggil dirinya sendiri
misal. kita akan mengubah funct countDown yg biasanya menggunakan literasi
seperti for, foreach, while seperti kode dibawah ini menjadi bentuk rekursif
*/
console.log("----fungsi count down----");
const countDown = start => {
do {
console.log(start);
start -=1;
}
while(start>0);
};
countDown(10); // belum rekursif
// diubah menjadi rekursih sbb :
console.log("count down versi rekursif")
const hitungMundur = mulai => {
console.log(mulai);
if(mulai>0) hitungMundur(mulai-1);
};
hitungMundur(20);
// dg teknik rekursif, kita sebenarnya bs menggantikan operasi literasi dg rekursif
// namun tidak sebatas itu saja, dg rekursi kita dapat membuat dan mengolah
// data structure seperti tree dan array
/** --- Hi order function
* JS memiliki kemampuan first class funct.
* karena itu fungsi pada JS dapat diperlakukan layaknya sebuah data.
* kita bs menyimpan funct dalam variabel, memberikan funct sbg parameter pada
* fungsi lainnya hingga mengembalikan funct ke dalam funct
*
*/
const hello = ()=> {
console.log('hellll-ooo!')
};
const say = (someFunction) => {
someFunction();
}
const sayHello = () =>{
return ()=> {
console.log('hellll-oo0');
}
}
hello();
say(hello);
sayHello()();
/* karena kemampuan first class funct ini, kita dapat membuat hi order funct dengan mudah
* hi order funct merupakan fungsi yang dpt menerima fungsi lainnya pada argumen, mengembalikan sebuah fungsi, atau bahkan keduanya
* teknik ini biasa digunakan utk :
* a. mengabstraksi atau mengisolasi sebuah event, aksi atau menangani alur asynchronous menggunakan call back, promise dsb
* b. membuat utilitis yg dpt digunakan d berbagai tipe data
* c. membuat teknik currying atau funct composition
*
* Array map() merupakan slh satu cntoh hi order function yg ada di JS.
* karenanya, ia menerima satu buah argumen yang merupakan sbuah funct.
*/
const names1 = ['hari', 'roen', 'jeffff', 'tomes'];
const arrayMap = (arr, action)=> {
const looopTrough = (arr, action, newArray = [], index = 0)=> {
const item = arr[index];
if(!item) return newArray;
return looopTrough(arr,action, [... newArray, action(arr[index])], index+1);
}
return looopTrough(arr,action);
}
const newNames1 = arrayMap(names1, (name)=> `${name}!`);
console.log({
names1, newNames1,
});
/** --- reusable Funct ---
* artinya adalah bahwa fungsi berparadigma FP adalah pure sehingga tidak
* terpengaruh oleh keadaan di luar atau dr luar. hal ini tentu membuat suatu funct dpt digunakan berkali kali
* tanpa khawatir mendapatkan hasil di luar ekspektasi
* beberapa contoh funct yg sifatnya reusable khususnya adalah hi order funct seperti array.map,
* array.filter, dan arrayforEach
*/
// array.map
// merupakan fungsi bawaan, dapat dipanggil dr sebuah data bertipe array dan menerima satu callback
const newArray1 = ['harii', 'rone', 'jefff', 'tomaz'].map((name)=> {return `${name}!`});
console.log(newArray1);
// fungsi map akan mengembalikan array baru. nilai per item pada array yang dikembalikan, dihasilkan dari kembalian callback funct
// karena callback funct dapat mengakses item array.
// array.filter
// funct ini berguna utk melakukan proses penyaringan thd nlai array yg ada.
// dapat digunakan utk menghilangkan beberapa item array berdasar spesifikasi tertentu
// cara kerja mirip array.map namun callbacknya dr fungsi ini mengembalkan booblean
//dimana bolean ini digunakan utk menentukan item array lolos saring atau tidak
// funct dibawah utk menghilangkan seluruh nilai Bolean(true) pada array
const trutyArray = [1, '', 'halooo', 0, null, 'harrrrry', 14].filter((item) => Boolean(item));
console.log(trutyArray); //contoh 1
console.log(' -------- ');
const student = [
{
nama2: 'heria',
score: 60,
},
{
nama2: 'jamesh',
score: 88
},
{
nama2: 'kung pao',
score: 75
}
];
const dapatBeasiswa = student.filter((student)=> student.score>80);
console.log(dapatBeasiswa); //contoh 2
//aray.reduce
// arr.reduce(callback(accumulator, currentValue, [currentIndex], [array]), [initialValue])
// [ ...] adalah opsional parameter
//callback funct dr funct ni dapat diolah utk dimanipulasi data curretValue dan menyimpannya dalam accumulator
// selain itu fungsi reduce memiliki nilai awal yang dapat didefinisikan pada bagian initialValue.
// contoh penggunaan pada funct menjumlahkan total nilai siswa
// menggunakan objek students
const totalScore = student.reduce((acc, student)=> acc+ student.score,0);
console.log(totalScore);
//array.some
//funct ini menghasilkan nilai boolean
// arr.some(callback(element, [index],[array]), [thsArg])
// [...] adalah opsional parameter
// nilai yg dihasilkan berdasarkan pada pernyatan pakah ada setidaknya satu dari deretan nilai dalam array
// yang lolos berdasarkan kriteria yang kita tuliskan dalam callback func.
// contoh penggunaan utk mengetahui deretan angka terdapat angka genap
const arrr = [1,2,3,6,7,8];
const even = arrr.some(element=> element%2 ===0);
console.log(even); //bernilai true karna ada elemen genap
//array.find
// mirip dengan array.some(), digunakan utk mencari apakah di dalam deretan nilai terdapat
// nilai yg sesuai dg kriteria yg didefinisikan
// yg membedakan adalah, array.find menghasilkan satu nilai dr elemen yg pertama kali ditemukan
// berdasarkan kriteria tertentu dan akan menghaslkan nilai undefine apabila tidak ada kriteria yg cocok
// arr.find(callback(element, [index], [array]), [thisArg]);
// [ ...] adl opsional parameter
// sbg contoh kita akan mencari siswa bernama 'james'
// kita pakai student
const cariJamesh = student.find(student => student.nama2 === 'jamesh');
console.log(cariJamesh);
//array sort
// berguna tuk melakukan pengurutan nilai dari sebuah deretan nilai.
//secara default, fungsi sort akan mengubah semua nilai dalam deretan menjadi bentuk string dan mengurutkannya scr ascending
//arr.sort([compareFunct])
// [...] adalah opsional parameter
//contoh sbb:
const bulan = ['maret', 'jan', 'feb', 'des'];
bulan.sort();
console.log(bulan); // diurutkan berdasar huruf depanny sj
// output : [ 'des', 'feb', 'jan', 'maret' ]
const arrray = [1,3,22,3,100,111]; //sorting hanya angka depanny saja wkwk
arrray.sort();
console.log(arrray);
// contoh pengurutan diatas berdasar pada pengurutan bentuk tipe data string
// jika kita ingin mengurutkan sesuai dg kriteria yg kita inginkan, maka perlu membuat compare funct sendiri
const arrr1 = [1,33,40,120,3];
const compareNumber = (a,b)=>{
return a-b;
};
const sorting = arrr1.sort(compareNumber);
console.log(sorting); // ini baru pass
// pada compare funct, fungsi akan membandingkan 2 nilai yg menghasilkan 3 kemungkinan
// negatif, positif atau 0
// jika negatif maka a,b
// jika positif maka b,a
// jika nol maka tidak ada perubahan
//array.every
// merupakan fungsi yang cek semua nilai dr sebuah array apakah sesuai dg kriteria yg didefinisikan
// kembalian nilai dr funct ini adalah boolean
// arr. every(callback(element, [index], [array]))
// sbg contoh, kita akan mengecek apakah seorang siswa tlh lulus semua uji materi
const skors = [70,85, 61];
const minimSkor = 65;
const lulusKor = skors.every(skors => skors >= minimSkor);
console.log(lulusKor); //false karna ada yg <65
//array,forEach
// funct utk memanggil funct callback pada setiap iterasi index array.
// funct ini tdk mengembalikan nilai apapun.
// fungsi hanya memanggil fungi callbacknya not more.
//contoh pake newArray1
console.log(newArray1);
for(let i=0;i<newArray1.length;i++){
console.log(`helooo, ${newArray1[i]}`);
} //cara imperatif
console.log(' ----------');
newArray1.forEach((newArray1)=>{
console.log(`hello, ${newArray1}`);
}); //cara deklaratif
//ketahuilah bahwa ketika menggunakan forEach, kita tdk bs menggunakan operator break atau continue
// pada proses perulangan( anda bs melakukannya pada perulangan for)
// hal ini juga berlaku ketika pada funct map dan filter
const apel = ['malang', 'brastagi', 'california'];
for(let i=0;i< apel.length;i++){
if(apel[i]==='brastagi') continue; //bisa
console.log(`helloooo, ${apel[i]}`);
}
/**
*
apel.forEach((apel)=>{
if(apel==='brastagi') continue; //tidak bs
console.log(`helo, ${apel[i]}`);
});
nb : jika di run atau tidak dijadikan komen akan error
*/