Thursday, January 16, 2020

forEach, map, filter, find, every, some, reduce in pure js implementation

These are normal functions but can be implemented with Array.prototype as well.

 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
// ForEach loop
const myForEach = (array, cb) => {
  for (let i = 0; i < array.length; i++) {
    cb(array[i], i, array)
  }
}

// map function
const myMap = (array, cb) => {
  const result = []
  for (let i = 0; i < array.length; i++) {
    result.push(cb(array[i], i, array))
  }
  return result
}

// Find first element if predicate is passed
const myFilter = (array, cb) => {
  const result = []
  for (let i = 0; i < array.length; i++) {
    if (cb(array[i], i, array)) {
      result.push(array[i])
    }
  }
  return result
}

// Find first element if predicate is passed
const myFind = (array, cb) => {
  for (let i = 0; i < array.length; i++) {
    if (cb(array[i], i, array)) {
      return array[i]
    }
  }
  return null
}

// If all of the elemnts pass the predicate
const myEvery = (array, cb) => {
  for (let i = 0; i < array.length; i++) {
    if (!cb(array[i], i, array)) {
      return false
    }
  }
  return true
}

// If some of the elemnts pass the predicate
const mySome = (array, cb) => {
  for (let i = 0; i < array.length; i++) {
    if (cb(array[i], i, array)) {
      return true
    }
  }
  return false
}
const myReduce = (array, callback, initialVal) => {
  for (let i = 0; i < array.length; i++) {
    initialVal = initialVal ? callback(initialVal, array[i], i, array) : array[i]
  }
  return initialVal
}

// TESTING
const aa = [1, 2, 3]

console.log('===== MY FOREACH ======')
myForEach(aa, a => console.log(a))

console.log('\n\n===== MY MAP ======')
const retOfMyMap = myMap(aa, a => a * 2)
myForEach(retOfMyMap, a => console.log(a))

console.log('\n\n===== MY FILTER ======')
const retOfMyFilter = myFilter(aa, a => a % 2 === 1)
myForEach(retOfMyFilter, a => console.log(a))

console.log('\n\n===== MY FIND ======')
const retOfMyFind = myFind(aa, a => a > 1)
console.log(retOfMyFind)

console.log('\n\n===== MY EVERY ======')
const retOfMyEvery = myEvery(aa, a => a > 0)
console.log(retOfMyEvery)

console.log('\n\n===== MY SOME ======')
const retOfMySome = mySome(aa, a => a > 10)
console.log(retOfMySome)

console.log('\n\n===== MY REDUCE ======')
const retOfMyReduce = myReduce(aa, (a, b) => a * b)
console.log(retOfMyReduce)


Since these are normal functions that is why we have taken the reference of array as a part of functional parameters, but when we make the functions as a part of array prototype then all references of 'array' can be changed to this., like:

1
2
3
4
5
Array.prototype.myForEach = function(cb) {
  for (let i = 0; i < this.length; i++) {
    cb(this[i], i, this)
  }
}

NOTE: Here in this function we did not use the arrow functions, the reason is simple, if we use the arrow functions the lexical scope of the function will be the function itself and not around the array value that called the function, and that is the reason we placed the normal function instead of arrow functions.
You can take more info from: https://stackoverflow.com/questions/36225636/function-to-array-prototype

Happy coding
:)

1 comment: