# 陣列迭代

1. `forEach`
2. `map`
3. `filter`
4. `some`
5. `every`
6. `reduce`

## forEach

• 執行步驟：

1. 迭代整個陣列
2. 對每一個值（value）執行一次 callback
3. 回傳 `undefined`
• 運行機制：

``````function forEach(arr, callback) {
for (let i = 0; i < arr.length; ++i) {
callback(arr[i], i, arr);
}
}
``````

1. Write a function called `doubleValues` which accepts an array and returns a new array with all the values in the array passed to the function doubled.

• Examples:

``````doubleValues([1, 2, 3]);
// [2, 4, 6]

doubleValues([5, 1, 2, 3, 10]);
// [10, 2, 4, 6, 20]
``````
• Solution:

``````function doubleValues(arr) {
let newArr = [];
arr.forEach((val) => newArr.push(val * 2));
return newArr;
}
``````
2. Write a function called `onlyEvenValues` which accepts an array and returns a new array with only the even values in the array passed to the function.

• Examples:

``````onlyEvenValues([1, 2, 3]);
// [2]

onlyEvenValues([5, 1, 2, 3, 10]);
// [2, 10]
``````
• Solution:

``````function onlyEvenValues(arr) {
let newArr = [];
arr.forEach((val) => {
if (val % 2 === 0) {
newArr.push(val);
}
});
return newArr;
}
``````
3. Write a function called `showFirstAndLast` which accepts an array of strings and returns a new array with only the first and last character of each string.

• Examples:

``````showFirstAndLast(['colt', 'matt', 'tim', 'udemy']);
// ['ct', 'mt', 'tm', 'uy']

showFirstAndLast(['hi', 'goodbye', 'smile']);
// ['hi', 'ge', 'se']
``````
• Solution:

``````function showFirstAndLast(arr) {
let newArr = [];
arr.forEach((val) => newArr.push(val[0] + val[val.length - 1]));
return newArr;
}
``````
4. Write a function called `addKeyAndValue` which accepts an array of objects, a key, and a value and returns the array passed to the function with the new key and value added for each object.

• Examples:

``````addKeyAndValue(
[{ name: 'Elie' }, { name: 'Colt' }],
'title',
'instructor'
);
// [{ name: 'Elie', title: 'instructor' },
//  { name: 'Colt', title: 'instructor' }]
``````
• Solution:

``````function addKeyAndValue(arr, key, value) {
arr.forEach((val) => (val[key] = value));
return arr;
}
``````
5. Write a function called `vowelCount` which accepts a string and returns an object with the keys as the vowel and the values as the number of times the vowel appears in the string. This function should be case insensitive so a lowercase letter and uppercase letter should count.

• Examples:

``````vowelCount('Elie');
// { e: 2, i: 1 }

vowelCount('Colt');
// { o: 1 }

vowelCount('hmmm');
// {};

vowelCount('I Am awesome and so are you');
// { i: 1, a: 4, e: 3, o: 3, u: 1 }
``````
• Solution:

``````function vowelCount(str) {
let obj = {};
let vowels = 'aeiou';
str
.toLowerCase()
.split('')
.forEach((val) => {
if (vowels.indexOf(val) !== -1) {
if (obj[val]) {
++obj[val];
} else {
obj[val] = 1;
}
}
});
return obj;
}
``````

## map

• 執行步驟：

1. 創建一個新的陣列（newArr）
2. 迭代原本的陣列（arr）
3. 對每一個值（value）執行一次 callback
4. 將 callback 函式回傳的結果加入步驟一所建立的陣列（newArr）
5. 回傳 newArr
• 運行機制：

``````function map(arr, callback) {
let newArr;
for (let i = 0; i < arr.length; ++i) {
newArr.push(callback(arr[i], i, arr));
}
return newArr;
}
``````

1. Write a function called `doubleValues` which accepts an array and returns a new array with all the values in the array passed to the function doubled.

• Examples:

``````doubleValues([1, 2, 3]);
// [2, 4, 6]

doubleValues([1, -2, -3]);
// [2, -4, -6]
``````
• Solution:

``````function doubleValues(arr) {
return arr.map((val) => val * 2);
}
``````
2. Write a function called `valTimesIndex` which accepts an array and returns a new array with each value multiplied by the index it is currently at in the array.

• Examples:

``````valTimesIndex([1, 2, 3]);
// [0, 2, 6]

valTimesIndex([1, -2, -3]);
// [0, -2, -6]
``````
• Solution:

``````function valTimesIndex(arr) {
return arr.map((val, i) => val * i);
}
``````
3. Write a function called `extractKey` which accepts an array of objects and some key and returns a new array with the value of that key in each object.

• Examples:

``````extractKey([{ name: 'Elie' }, { name: 'Colt' }], 'name');
// ['Elie', 'Colt']
``````
• Solution:

``````function extractKey(arr, key) {
return arr.map((val) => val[key]);
}
``````
4. Write a function called `extractFullName` which accepts an array of objects and returns a new array with the value of the key with a name of ‘first’ and the value of a key with the name of ‘last’ in each object, concatenated together with a space.

• Examples:

``````extractFullName([
{ first: 'Elie', last: 'Schoppik' },
{ first: 'Colt', last: 'Steele' },
]);
// ['Elie Schoppik', 'Colt Steele']
``````
• Solution:

``````function extractFullName(arr) {
return arr.map((val) => `\${val.first} \${val.last}`);
}
``````

## filter

• 執行步驟：

1. 創建一個新的陣列（newArr）
2. 迭代原本的陣列（arr）
3. 對每一個值（value）執行一次 callback
• 若 callback 回傳 `true`，將 value 加入步驟一所建立的陣列（newArr）
• 若 callback 回傳 `false`，continue
4. 回傳 newArr
• 運行機制：

``````function filter(arr, callback) {
let newArr;
for (let i = 0; i < arr.length; ++i) {
if (callback(arr[i], i, arr)) {
newArr.push(arr[i]);
}
}
return newArr;
}
``````

1. Write a function called `filterByValue` which accepts an array of objects and a key and returns a new array with all the objects that contain that key.

• Examples:

``````filterByValue(
[
{ first: 'Elie', last: 'Schoppik' },
{ first: 'Colt', last: 'Steele', isCatOwner: true },
],
'isCatOwner'
);
// [{ first: 'Colt', last: 'Steele', isCatOwner: true }]
``````
• Solution:

``````function filterByValue(arr, key) {
return arr.filter((val) => val[key]);
}
``````
2. Write a function called `find` which accepts an array and a value and returns the first element in the array that has the same value as the second parameter or undefined if the value is not found in the array.

• Examples:

``````find([1, 2, 3, 4, 5], 3);
// 3

find([1, 2, 3, 4, 5], 10);
// undefined
``````
• Solution:

``````function find(arr, searchValue) {
return arr.filter((val) => val === searchValue)[0];
}
``````
3. Write a function called `findInObj` which accepts an array of objects, a key, and some value to search for and returns the first found value in the array.

• Examples:

``````findInObj(
[
{ first: 'Elie', last: 'Schoppik' },
{ first: 'Tim', last: 'Garcia', isCatOwner: true },
{ first: 'Colt', last: 'Steele', isCatOwner: true },
],
'isCatOwner',
true
);
// { first: 'Tim', last: 'Garcia', isCatOwner: true}
``````
• Solution:

``````function findInObj(arr, key, searchValue) {
return arr.filter((val) => val[key] === searchValue)[0];
}
``````
4. Write a function called `removeVowels` which accepts a string and returns a new string with all of the vowels (both uppercased and lowercased) removed. Every character in the new string should be lowercased.

• Examples:

``````removeVowels('Elie');
// 'l'

removeVowels('TIM');
// 'tm'

removeVowels('ZZZZZZ');
// 'zzzzzz'
``````
• Solution:

``````function removeVowels(str) {
let vowels = 'aeiou';
return str
.toLowerCase()
.split('')
.filter((val) => vowels.indexOf(val) === -1)
.join('');
}
``````
5. Write a function called `doubleOddNumbers` which accepts an array and returns a new array with all of the odd numbers doubled (HINT - you can use map and fitler to double and then filter the odd numbers).

• Examples:

``````doubleOddNumbers([1, 2, 3, 4, 5]);
// [2, 6, 10]

doubleOddNumbers([4, 4, 4, 4, 4]);
// []
``````
• Solution:

``````function doubleOddNumbers(arr) {
return arr.filter((val) => val % 2 === 1).map((val) => val * 2);
}
``````

## some

• 執行步驟：

1. 迭代原本的陣列（arr）
2. 對每一個值（value）執行一次 callback
• 若至少有一個 callback 回傳 `true`，則回傳 `true`
• 否則，回傳 `false`
• 運行機制：

``````function some(arr, callback) {
for (let i = 0; i < arr.length; ++i) {
if (callback(arr[i], i, arr)) {
return true;
}
}
return false;
}
``````

## every

• 執行步驟：

1. 迭代原本的陣列（arr）
2. 對每一個值（value）執行一次 callback
• 若至少有一個 callback 回傳 `false`，則回傳 `fale`
• 否則，回傳 `true`
• 運行機制：

``````function every(arr, callback) {
for (let i = 0; i < arr.length; ++i) {
if (callback(arr[i], i, arr) === false) {
return false;
}
}
return true;
}
``````

1. Write a function called `hasOddNumber` which accepts an array and returns `true` if the array contains at least one odd number, otherwise it returns `false`.

• Examples:

``````hasOddNumber([1, 2, 2, 2, 2, 2, 4]);
// true

hasOddNumber([2, 2, 2, 2, 2, 4]);
// false
``````
• Solution:

``````function hasOddNumber(arr) {
return arr.some((val) => val % 2 === 1);
}
``````
2. Write a function called `hasAZero` which accepts a number and returns `true` if that number contains at least one zero. Otherwise, the function should return `false`.

• Examples:

``````hasAZero(3332123213101232321);
// true

hasAZero(1212121);
// false
``````
• Solution:

``````function hasAZero(num) {
return num
.toString()
.split('')
.some((val) => val === '0');
}
``````
3. Write a function called `hasOnlyOddNumbers` which accepts an array and returns `true` if every single number in the array is odd. If any of the values in the array are not odd, the function should return `false`.

• Examples:

``````hasOnlyOddNumbers([1, 3, 5, 7]);
// false

hasOnlyOddNumbers([1, 2, 3, 5, 7]);
// false
``````
• Solution:

``````function hasOnlyOddNumbers(arr) {
return arr.every((val) => val % 2 === 1);
}
``````
4. Write a function called `hasNoDuplicates` which accepts an array and returns `true` if there are no duplicate values (more than one element in the array that has the same value as another). If there are any duplicates, the function should return `false`.

• Examples:

``````hasNoDuplicates([1, 2, 3, 1]);
// false

hasNoDuplicates([1, 2, 3]);
// true
``````
• Solution:

``````function hasNoDuplicates(arr) {
return arr.every((val) => arr.indexOf(val) === arr.lastIndexOf(val));
}
``````
5. Write a function called `hasCertainKey` which accepts an array of objects and a key, and returns `true` if every single object in the array contains that key. Otherwise it should return `false`.

• Examples:

``````const arr = [
{ title: 'Instructor', first: 'Elie', last: 'Schoppik' },
{ title: 'Instructor', first: 'Tim', last: 'Garcia', isCatOwner: true },
{ title: 'Instructor', first: 'Matt', last: 'Lane' },
{ title: 'Instructor', first: 'Colt', last: 'Steele', isCatOwner: true },
];

hasCertainKey(arr, 'first');
// true

hasCertainKey(arr, 'isCatOwner');
// false
``````
• Solution:

``````function hasCertainKey(arr, key) {
return arr.every((val) => key in val);
}
``````
6. Write a function called `hasCertainValue` which accepts an array of objects and a key, and a value, and returns `true` if every single object in the array contains that value for the specific key. Otherwise it should return `false`.

• Examples:

``````let arr = [
{ title: 'Instructor', first: 'Elie', last: 'Schoppik' },
{ title: 'Instructor', first: 'Tim', last: 'Garcia', isCatOwner: true },
{ title: 'Instructor', first: 'Matt', last: 'Lane' },
{ title: 'Instructor', first: 'Colt', last: 'Steele', isCatOwner: true },
];

hasCertainValue(arr, 'title', 'Instructor');
// true

hasCertainValue(arr, 'first', 'Elie');
// false
``````
• Solution:

``````function hasCertainValue(arr, key, searchValue) {
return arr.every((val) => val[key] === searchValue);
}
``````

## reduce

• 執行步驟

1. 參數：
• 1.（必要）callback 函式
• 2.（可有可無）第二個參數（optional parameter）
2. 迭代原本的陣列（arr）
3. 對每一個值（value）執行一次 callback
• 若有提供 optional parameter 的話，callback 的第一個參數便是該 optional parameter
• 否則，則是 arr[0]，也就是第 0 個 value
• 通常我們稱呼 callback 的第一個參數為 ‘accumulator’，常用縮寫為 acc
4. 每次從 callback 回傳的值，變成為新的 accumulator！

1. 無 optional parameter，最後回傳結果為 6。

``````const arr = [1, 2, 3];
arr.reduce((acc, next) => acc + next);
``````
accumulator nextValue returned value
1 2 3
3 3 6
2. 有 optional parameter，最後回傳結果為 16。

``````const arr = [1, 2, 3];
arr.reduce((acc, next) => acc + next, 10);
``````
accumulator nextValue returned value
10 1 11
11 2 13
13 3 16

1. Write a function called `extractValue` which accepts an array of objects and a key and returns a new array with the value of each object at the key.

• Examples:

``````const arr = [{ name: 'Elie' }, { name: 'Colt' }];
extractValue(arr, 'name');
// ['Elie', 'Colt']
``````
• Solution:

``````function extractValue(arr, key) {
return arr.reduce((acc, next) => {
acc.push(next[key]);
return acc;
}, []);
}
``````
2. Write a function called `vowelCount` which accepts a string and returns an object with the keys as the vowel and the values as the number of times the vowel appears in the string. This function should be case insensitive so a lowercase letter and uppercase letter should count

• Examples:

``````vowelCount('Elie');
// { e: 2, i: 1 }

vowelCount('Colt');
// { o: 1 }

vowelCount('hmmm');
// {};

vowelCount('I Am awesome and so are you');
// { i: 1, a: 4, e: 3, o: 3, u: 1 }
``````
• Solution:

``````function vowelCount(str) {
const vowels = 'aeiou';
return str
.toLowerCase()
.split('')
.reduce((acc, next) => {
if (vowels.indexOf(next) !== -1) {
if (acc[next]) {
++acc[next];
} else {
acc[next] = 1;
}
}
return acc;
}, {});
}
``````
3. Write a function called `addKeyAndValue` which accepts an array of objects, a key, and a value and returns the array passed to the function with the new key and value added for each object.

• Examples:

``````addKeyAndValue(
[{ name: 'Elie' }, { name: 'Colt' }],
'title',
'instructor'
);
// [{ name: 'Elie', title: 'instructor' },
//  { name: 'Colt', title: 'instructor' }]
``````
• Solution:

``````function addKeyAndValue(arr, key, value) {
return arr.reduce((acc, next, i) => {
acc[i][key] = value;
return acc;
}, arr);
}
``````
4. Write a function called `partition` which accepts an array and a callback and returns an array with two arrays inside of it. The partition function should run the callback function on each value in the array and if the result of the callback function at that specific value is true, the value should be placed in the first subarray. If the result of the callback function at that specific value is false, the value should be placed in the second subarray.

• Examples:

``````function isEven(val) {
return val % 2 === 0;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8];
partition(arr, isEven);
// [[2, 4, 6, 8], [1, 3, 5, 7]];

function isLongerThanThreeCharacters(val) {
return val.length > 3;
}
const names = ['Elie', 'Colt', 'Tim', 'Matt'];
partition(names, isLongerThanThreeCharacters);
// [['Elie', 'Colt', 'Matt'], ['Tim']]
``````
• Solution:

``````function partition(arr, callback) {
return arr.reduce(
(acc, next, i) => {
if (callback(next)) {
acc[0].push(next);
} else {
acc[1].push(next);
}
return acc;
},
[[], []]
);
}
``````

2954 Words

2018-07-20 00:26 -0400