Working With Arrays

vancouver·2023년 6월 15일
0

javascript이해하기

목록 보기
17/22

Simple Array Methods

let arr = [`a`, `b`, `c`, `d`, `e`];

// SLICE
console.log(arr.slice(2)); // ['c', 'd', 'e']
console.log(arr.slice(2, 4)); // ['c', 'd']
console.log(arr.slice(-2)); // ['d', 'e']
console.log(arr.slice(-1)); // ['e']
console.log(arr.slice(1, -2)); //  ['b', 'c']
console.log(arr.slice()); //  ['a', 'b', 'c', 'd', 'e']
console.log([...arr]); //  ['a', 'b', 'c', 'd', 'e']

// SPLICE (배열에서 삭제)
// console.log(arr.splice(2));
arr.splice(-1);
console.log(arr); // ['a', 'b']
arr.splice(1, 2);
console.log(arr); // ['a']

// REVERSE (뒤바뀜)
arr = [`a`, `b`, `c`, `d`, `e`];
const arr2 = [`j`, `i`, `h`, `g`, `f`];
console.log(arr2.reverse()); // ['f', 'g', 'h', 'i', 'j']
console.log(arr2); // ['f', 'g', 'h', 'i', 'j']

// CONCAT
const letters = arr.concat(arr2);
console.log(letters); //  ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
console.log([...arr, ...arr2]); //  ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

// JOIN
console.log(letters.join(` - `)); // a - b - c - d - e - f - g - h - i - j

Looping Arrays: for Each (Set and Map)

const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];

// for (const movement of movements) {
for (const [i, movement] of movements.entries()) {
  if (movement > 0) {
    console.log(`Movement ${i + 1}: You deposited ${movement}`);
  } else {
    console.log(`Movement ${i + 1}: You withdrew ${Math.abs(movement)}`);
  }
}/*
  Movement 1: You deposited 200
  Movement 2: You deposited 450
  Movement 3: You withdrew 400
  Movement 4: You deposited 3000
  Movement 5: You withdrew 650
  Movement 6: You withdrew 130
  Movement 7: You deposited 70
  Movement 8: You deposited 1300 */

console.log(`---- FOR EACH ----`);

movements.forEach(function (mov, i, arr) {
  if (mov > 0) {
    console.log(`Movement ${i + 1}: You deposited ${mov}`);
  } else {
    console.log(`Movement ${i + 1}: You withdrew ${Math.abs(mov)}`);
  }
});
// 0: function(200)
// 1: function(450)
// 2: function(400)
// ...
// Map
const currencies = new Map([
  ["USD", "United States dollar"],
  ["EUR", "Euro"],
  ["GBP", "Pound sterling"],
]);

currencies.forEach(function (value, key, map) {
  console.log(`${key}: ${value}`); /*
  USD: United States dollar
  EUR: Euro
  GBP: Pound sterling */
});

// Set
const currenciesUnique = new Set([`USD`, `GBP`, `USD`, `EUR`, `EUR`]);
console.log(currenciesUnique); /*
Set(3) {'USD', 'GBP', 'EUR'}
[[Entries]]
0: "USD"
1: "GBP"
2: "EUR"
size: 3
[[Prototype]]: Set */
currenciesUnique.forEach(function (value, _, map) { 
  console.log(`${value}: ${value}`); /* 
  USD: USD
  GBP: GBP
  EUR: EUR */
});

insertAdjacentHTML

https://developer.mozilla.org/ko/docs/Web/API/Element/insertAdjacentHTML

구문

element.insertAdjacentHTML(position, text);

position은 아래 있는 단어만 사용 가능하다.

'beforebegin'
element 앞에

'afterbegin'
element 안에 가장 첫번째 child

'beforeend'
element 안에 가장 마지막 child

'afterend'
element 뒤에

text(인자)는 HTML 또는 XML로 해석될 수 있는 문자열이고(html code), (DOM) tree에 삽입할 수 있다.

position의 예시 그림

<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->

예시

const displayMovements = function (movements) {
  containerMovements.innerHTML = ``;

  movements.forEach(function (mov, i) {
    const type = mov > 0 ? `deposit` : `withdrawal`;

    const html = `
  <div class="movements__row">
  <div class="movements__type movements__type--${type}">${i + 1} ${type}</div>
  <div class="movements__value">${mov}</div>
</div>
  `;

    containerMovements.insertAdjacentHTML(`afterbegin`, html);
    /*  <div class="movements__row">
  <div class="movements__type movements__type--${type}">${i + 1} ${type}</div>
  <div class="movements__value">${mov}</div>
</div> */
  });
};

Coding Challenge #1

// Coding Challenge #1

/* 
줄리아와 케이트는 개에 대한 연구를 진행하고 있습니다. 각각 5명의 개 주인에게 개의 나이에 대해 물어보고 데이터를 배열에 저장했습니다 (각각 하나의 배열). 현재는 개가 어른인지 아니면 강아지인지만 알고 싶어합니다.
개는 최소 3살 이상이면 어른이고, 3살 미만이면 강아지입니다 */

/*
1. 줄리아는 첫 번째와 마지막 두 개의 개 주인들이 사실 고양이를 가지고 있다는 것을 알아냈습니다! 
따라서 줄리아의 배열을 얕은 복사하고, 그 복사된 배열에서 고양이의 나이를 제거해야 합니다 (함수 매개변수를 변경하는 것은 좋지 않은 방법입니다).
2. 줄리아와 케이트의 데이터를 포함한 배열을 만들어야 합니다.
3. 각 개에 대해 남아 있는 개들에 대해 콘솔에 출력하여 어른 개인지("Dog number 1 is an adult, and is 5 years old") 아니면 강아지인지("Dog number 2 is still a puppy") 알아야 합니다.
4. 두 개의 테스트 데이터 세트에 대해 함수를 실행해야 합니다. 위의 코드는 이미 준비되어 있으므로 각각의 데이터 세트에 대해 해당 코드를 실행하면 됩니다. */

/* Test data
Data 1: Julia's data [3, 5, 2, 12, 7], Kate's data [4, 1, 15, 8, 3]
Data 2: Julia's data [9, 16, 6, 8, 3], Kate's data [10, 5, 6, 1, 4] */

const checkDogs = function (dogsJulia, dogsKate) {
  const dogsJuliaCorrected = dogsJulia.slice();
  dogsJuliaCorrected.splice(0, 1);
  dogsJuliaCorrected.splice(-2);
  // dogsJuliaCorrected.slice(1, 3);
  console.log(dogsJuliaCorrected); // [5, 2]
  console.log(dogsKate); // [4, 1, 15, 8, 3]
  const dogs = dogsJuliaCorrected.concat(dogsKate);
  console.log(dogs); //  [5, 2, 4, 1, 15, 8, 3]

  //("Dog number 1 is an adult, and is 5 years old") or a puppy ("Dog number 2 is still a puppy 🐶"

  dogs.forEach(function (age, i) {
    if (age < 3) {
      console.log(`Dog number ${i + 1} is still a puppy🐶`);
    } else {
      console.log(`Dog number ${i + 1} is an adult, and is ${age} years old`);
    }
  });
};

checkDogs([3, 5, 2, 12, 7], [4, 1, 15, 8, 3]);/*
Dog number 1 is an adult, and is 5 years old
Dog number 2 is still a puppy🐶
Dog number 3 is an adult, and is 4 years old
Dog number 4 is still a puppy🐶
Dog number 5 is an adult, and is 15 years old
Dog number 6 is an adult, and is 8 years old
Dog number 7 is an adult, and is 3 years old */

Data Transformations: map, filter, reduce

Map

👉 map은 기존 배열의 모든 요소에 대해 작업을 적용한 결과를 포함하는 새로운 배열을 반환합니다.

Filter

👉 filter는 지정된 테스트 조건을 통과한 배열 요소를 포함하는 새로운 배열을 반환합니다.

Reduce

👉 reduce는 배열의 모든 요소를 하나의 값으로 축소하는 작업을 수행합니다. 예를 들어, 모든 요소를 더하는 작업을 수행할 수 있습니다.

The map Method

const movements = [200, 450, -400, 3000, -650, -130, 70, 1300];

const eurToUsd = 1.1;

// Traditional Function
 const movementsUSD = movements.map(function (mov) {
   return mov * eurToUsd;
 });

// Arrow Function
const movementsUSD = movements.map((mov) => mov * eurToUsd);

console.log(movements); // [200, 450, -400, 3000, -650, -130, 70, 1300]
console.log(movementsUSD); //  [220.00000000000003, 495.00000000000006, -440.00000000000006, 3300.0000000000005, -715.0000000000001, -143, 77, 1430.0000000000002]

const movementsUSDfor = [];
for (const mov of movements) movementsUSDfor.push(mov * eurToUsd);
console.log(movementsUSDfor); // [220.00000000000003, 495.00000000000006, -440.00000000000006, 3300.0000000000005, -715.0000000000001, -143, 77, 1430.0000000000002]

const movmentsDescriptions = movements.map(
  (mov, i) =>
    `Movement ${i + 1}: You ${mov > 0 ? `deposited` : `withdrew`} ${Math.abs(
      mov
    )}`
);
console.log(movmentsDescriptions);
/* 
0: "Movement 1: You deposited 200"
1: "Movement 2: You deposited 450"
2: "Movement 3: You withdrew 400"
3: "Movement 4: You deposited 3000"
4: "Movement 5: You withdrew 650"
5: "Movement 6: You withdrew 130"
6: "Movement 7: You deposited 70"
7: "Movement 8: You deposited 1300"
length: 8
[[Prototype]]: Array(0)*/

Computing Usernames

const account1 = {
  owner: "Jonas Schmedtmann",
  movements: [200, 450, -400, 3000, -650, -130, 70, 1300],
  interestRate: 1.2, // %
  pin: 1111,
};

const account2 = {
  owner: "Jessica Davis",
  movements: [5000, 3400, -150, -790, -3210, -1000, 8500, -30],
  interestRate: 1.5,
  pin: 2222,
};

const account3 = {
  owner: "Steven Thomas Williams",
  movements: [200, -200, 340, -300, -20, 50, 400, -460],
  interestRate: 0.7,
  pin: 3333,
};

const account4 = {
  owner: "Sarah Smith",
  movements: [430, 1000, 700, 50, 90],
  interestRate: 1,
  pin: 4444,
};

const accounts = [account1, account2, account3, account4];


// Traditional Function
 const createUserNames = function (accs) { // Steven Thomas Williams --> stw
   accs.forEach(function (acc) {
     acc.username = acc.owner
       .toLowerCase()
       .split(` `)
       .map((name) => name[0])
       .join(``);
   });
 };

// Arrow Function
const createUserNames = (accs) => // Steven Thomas Williams --> stw
  accs.forEach(
    (acc) =>
      (acc.username = acc.owner
        .toLowerCase()
        .split(` `)
        .map((name) => name[0])
        .join(``))
  );

createUserNames(accounts);

console.log(accounts);
/*
0: {owner: 'Jonas Schmedtmann', movements: Array(8), interestRate: 1.2, pin: 1111, username: 'js'}
1: {owner: 'Jessica Davis', movements: Array(8), interestRate: 1.5, pin: 2222, username: 'jd'}
2: {owner: 'Steven Thomas Williams', movements: Array(8), interestRate: 0.7, pin: 3333, username: 'stw'}
3: {owner: 'Sarah Smith', movements: Array(5), interestRate: 1, pin: 4444, username: 'ss'} */

The filter Method

// filter
const deposits = movements.filter(function (mov) {
  return mov > 0;
});

console.log(movements); // [200, 450, -400, 3000, -650, -130, 70, 1300]
console.log(deposits); // [200, 450, 3000, 70, 1300]

// for of loop
const depositsFor = [];
for (const mov of movements) if (mov > 0) depositsFor.push(mov);
console.log(depositsFor); // [200, 450, 3000, 70, 1300]

// filter (Arrow Function)
const withdrawls = movements.filter((mov) => mov < 0);
console.log(movements); // [200, 450, -400, 3000, -650, -130, 70, 1300]
console.log(withdrawls); // [-400, -650, -130]

// for of loop
const withdrawlsFor = [];
for (const mov of movements) if (mov < 0) withdrawlsFor.push(mov);
console.log(withdrawlsFor); // [-400, -650, -130]

The reduce Method

// accumulator  -> SNOWBALL

// Traditional Function
const balance1 = movements.reduce(function (acc, cur, i, arr) { 
  // 누산기 (acc), 현재 값 (cur), 현재 인덱스 (idx), 원본 배열 (arr)
  console.log(`Iteration ${i}: ${acc}`);/*
  Iteration 0: 0
  Iteration 1: 200
  Iteration 2: 650
  Iteration 3: 250
  Iteration 4: 3250
  Iteration 5: 2600
  Iteration 6: 2470
  Iteration 7: 2540 */
  return acc + cur;
}, 0); // 0은 초기값

// Arrow function
const balance = movements.reduce((acc, cur) => acc + cur, 0); // 0은 초기값
console.log(balance); // 3840

// for of loop
let balance2 = 0;
for (const mov of movements) balance2 += mov;
console.log(balance2); // 3840

// Maximum value
const max = movements.reduce((acc, mov) => {
  if (acc > mov) return acc;
  else return mov;
}, movements[0]);
console.log(max); // 3000

Coding Challenge #2

// Coding Challenge #2
/* 다음과 같이 동작하는 'calcAverageHumanAge'라는 함수를 생성해보겠습니다. 이 함수는 개의 나이 배열('ages')을 입력으로 받고, 다음 작업을 순서대로 수행합니다

1. 개의 인간 연령을 계산하기 위해 다음 공식을 사용하는 'calcAverageHumanAge'라는 함수를 생성해보겠습니다: 만약 개가 2세 이하인 경우, 인간 연령은 개의 연령 * 2가 됩니다. 
개가 2세를 초과하는 경우, 인간 연령은 16 + (개의 연령 - 2) * 4로 계산됩니다.


2.18세 이하의 인간 연령에 해당하는 개들을 제외하고자 한다면, 18세 이상인 개들만 배열 하는것이 좋습니다.

3. 모든 성체 개의 평균 인간 연령을 계산하려면, 평균을 계산하는 다른 도전에서 이미 배운 방법을 사용해야 합니다.

Data Test:
Data 1: [5, 2, 4, 1, 15, 8, 3]
Data 2: [16, 6, 10, 5, 6, 1, 4] */

const calcAverageHumanAge = function (ages) {
  const humanAges = ages.map((age) => (age <= 2 ? 2 * age : 16 + age * 4)); // 강아지의 나이가 2살 이하일때 2를 곱, 초과일땐 16 + 나이 * 4

  const adults = humanAges.filter((age) => age >= 18);
  console.log(humanAges); // [36, 4, 32, 2, 76, 48, 28] (강아지 나이를 성인나이로 환산)
  console.log(adults); //  [36, 32, 76, 48, 28] (18세 이상인 강아지만 배열)

  const averageAdults =
    adults.reduce((acc, age) => acc + age, 0) / adults.length; // 성인 강아지의 배열의 평균값

  return averageAdults;
};

const avg1 = calcAverageHumanAge([5, 2, 4, 1, 15, 8, 3]); 
const avg2 = calcAverageHumanAge([16, 6, 10, 5, 6, 1, 4]);
console.log(avg1, avg2); // 44  47.333333333333336

Chaining Method

const account1 = {
  owner: "Jonas Schmedtmann",
  movements: [200, 450, -400, 3000, -650, -130, 70, 1300],
  interestRate: 1.2, // %
  pin: 1111,
};

const calcDisplaySummary = function (movements) { // 총 입금 내역
  const incomes = movements
    .filter((mov) => mov > 0) // 0 보다 높은 숫자만 걸러냄
    .reduce((acc, mov) => acc + mov, 0); // 숫자들을 더함
  labelSumIn.textContent = `${incomes}`; // 입금내역의 디스플레이

  const out = movements // 총 출금 내역
    .filter((mov) => mov < 0) // 0 보다 작은 숫자만 걸러냄
    .reduce((acc, mov) => acc + mov, 0); // 숫자들을 더함
  labelSumOut.textContent = `${Math.abs(out)}`; // 출금내역의 디스플레이 (-기호 삭제)

  const interest = movements // 총 이자 내역
    .filter((mov) => mov > 0) // 0 보다 높은 숫자만 걸러냄
    .map((deposit) => (deposit * 1.2) / 100) // 이자율의 1.2%를 반영
    .filter((int, i, arr) => {
      console.log(arr); //[2.4, 5.4, 36, 0.84, 15.6]
      return int >= 1; // [0.84]를 제외
    })
    .reduce((acc, int) => acc + int, 0); // 숫자들을 더함
  labelSumInterest.textContent = `${interest}`; // 이자내역의 디스플레이
};
calcDisplaySummary(account1.movements);

/// EXAMPLE
const eurToUsd = 1.1;
console.log(movements); //  [200, 450, -400, 3000, -650, -130, 70, 1300]	

const toalDepositsUSD = movements
  .filter((mov) => mov > 0)
  .map((mov, i, arr) => {
    // console.log(arr);
    return mov * eurToUsd;
  })
  // .map((mov, i, arr) => mov * eurToUsd)
  .reduce((acc, mov) => acc + mov, 0);
console.log(toalDepositsUSD); // 5522.000000000001

Coding Challenge #3

// Coding Challenge #3
/* Rewrite the 'calcAverageHumanAge' function from Challenge #2, but this time 
as an arrow function, and using chaining! */

// Coding Challenge #2에서의 내용들을 arrow Function으로 바꾸고 chaining 하세요

// const calcAverageHumanAge = function (ages) {
//   const humanAges = ages.map((age) => (age <= 2 ? 2 * age : 16 + age * 4));

//   const adults = humanAges.filter((age) => age >= 18);

//   const averageAdults =
//     adults.reduce((acc, age) => acc + age, 0) / adults.length;

//   return averageAdults;
// };

const calcAverageHumanAge = (ages) =>
  ages
    .map((age) => (age <= 2 ? 2 * age : 16 + age * 4))
    .filter((age) => age >= 18)
    .reduce((acc, age, i, arr) => acc + age / arr.length, 0);

const avg1 = calcAverageHumanAge([5, 2, 4, 1, 15, 8, 3]);
const avg2 = calcAverageHumanAge([16, 6, 10, 5, 6, 1, 4]);
console.log(avg1, avg2);

The find Method

Filter는 조건에 해당하는 모든요소를 반환 배열로 반환
Find는 첫번째와 두번째만 반환 배열이 아닌 요소로반환

const firstWithdrawl = movements.find((mov) => mov < 0);
const filter = movements.filter((mov) => mov < 0);

console.log(movements); // [200, 450, -400, 3000, -650, -130, 70, 1300]
console.log(firstWithdrawl); // -400
console.log(filter); // (3) [-400, -650, -130]

console.log(accounts);
const account = accounts.find((acc) => acc.owner === `Jessica Davis`);

const accountFor = [];
for (const account of accounts)
  if (account.owner === `Jessica Davis`) accountFor.push(account);

console.log(account);/*	
{owner: 'Jessica Davis', movements: Array(8), interestRate: 1.5, pin: 2222, username: 'jd'}
interestRate: 1.5
movements: (8) [5000, 3400, -150, -790, -3210, -1000, 8500, -30]
owner: "Jessica Davis"
pin: 2222
username: "jd"
[[Prototype]]: Object */


console.log(accountFor);/*
0: {owner: 'Jessica Davis', movements: Array(8), interestRate: 1.5, pin: 2222, username: 'jd'}
length: 1
[[Prototype]]: Array(0) */

The findIndex Method

findIndex() 메서드는 주어진 판별 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스를 반환합니다. 만족하는 요소가 없으면 -1을 반환합니다.

Example :

const array1 = [5, 12, 8, 130, 44];

const isLargeNumber = (element) => element > 13;

console.log(array1.findIndex(isLargeNumber));
// Expected output: 3
btnClose.addEventListener(`click`, function (e) {
  e.preventDefault();
  currentAccount = accounts.find(
    (acc) => acc.username === inputCloseUsername.value
  );

  console.log(currentAccount);

  if (
    inputCloseUsername.value === currentAccount.username &&
    Number(inputClosePin.value) === currentAccount.pin
  ) {
    const index = accounts.findIndex(
      (acc) => acc.username === currentAccount.username
    );
    console.log(index);

    // Delete account
    accounts.splice(index, 1);

    // Hide UI
    containerApp.style.opacity = 0;
  }
  inputCloseUsername.value = inputClosePin.value = ``;
});

some and every

some() 메서드는 배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 테스트합니다. 만약 배열에서 주어진 함수가 true을 반환하면 true를 반환합니다. 그렇지 않으면 false를 반환합니다. 이 메서드는 배열을 변경하지 않습니다.
every() 메서드는 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트합니다. Boolean 값을 반환합니다.

console.log(movements); //[200, 450, -400, 3000, -650, -130, 70, 1300]

// EQUALITY
console.log(movements.includes(-130)); // true

// SOME: CONDITION
console.log(movements.some((mov) => mov === -130)); // true

const anyDeposits = movements.some((mov) => mov > 0);
console.log(anyDeposits); // true

// EVERY
console.log(movements.every((mov) => mov > 0)); // false
console.log(account4.movements.every((mov) => mov > 0)); // true

// Seperate callback
const deposit = (mov) => mov > 0;
console.log(movements.some(deposit)); // true
console.log(movements.every(deposit)); // false
console.log(movements.filter(deposit)); // [200, 450, 3000, 70, 1300]

flat and flatMap

flat() 메서드는 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성합니다.
flatMap() 메서드는 먼저 매핑함수를 사용해 각 엘리먼트에 대해 map 수행 후, 결과를 새로운 배열로 평탄화합니다. 이는 깊이 1의 flat 이 뒤따르는 map 과 동일하지만, flatMap 은 아주 유용하며 둘을 하나의 메소드로 병합할 때 조금 더 효율적입니다.

const arr = [[1, 2, 3], [4, 5, 6], 7, 8];
console.log(arr.flat()); // [1, 2, 3, 4, 5, 6, 7, 8]

const arrDeep = [[[1, 2], 3], [4, [5, 6]], 7, 8];
console.log(arrDeep.flat()); // [Array(2), 3, 4, Array(2), 7, 8]
console.log(arrDeep.flat(1)); // [Array(2), 3, 4, Array(2), 7, 8]
console.log(arrDeep.flat(2)); // [1, 2, 3, 4, 5, 6, 7, 8]

// const accountMovements = accounts.map((acc) => acc.movements);
// console.log(accountMovements); // [Array(8), Array(8), Array(8), Array(5)]
// const allMovements = accountMovements.flat();
// console.log(allMovements); // (29) [200, 450, -400, 3000, -650, -130, 70, 1300, 5000, 3400, -150....]
// const overalBalance = allMovements.reduce((acc, mov) => acc + mov, 0);
//-----------------------리 팩 터 링------------------------//

// flat
const overalBalance = accounts
  .map((acc) => acc.movements)
  .flat()
  .reduce((acc, mov) => acc + mov, 0);
console.log(overalBalance); // 17840

// flatMap
const overalBalance2 = accounts
  .flatMap((acc) => acc.movements)
  .reduce((acc, mov) => acc + mov, 0);
console.log(overalBalance2); // 17840

sorting Arrays (sort Method)

sort() 메서드는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환합니다

// String
const owners = [`Jonas`, `Zach`, `Adam`, `Martha`];
console.log(owners.sort()); // ['Adam', 'Jonas', 'Martha', 'Zach']
console.log(owners); // ['Adam', 'Jonas', 'Martha', 'Zach'] (sortMethod를 사용한후 배열의 위치가 달라짐으로 사용할때 조심해야함)

// Number
console.log(movements); //  [200, 450, -400, 3000, -650, -130, 70, 1300]
console.log(movements.sort()); // [-130, -400, -650, 1300, 200, 3000, 450, 70] (마이너스(-)가 우선순위 다음 숫자 1부터 순위)

// return < 0 A, B (keep order)
// return > 0 B, A (switch order)

// Ascending
// movements.sort((a, b) => {
//   if (a > b) return 1; // [-650, -400, -130, 70, 200, 450, 1300, 3000]
//   if (a < b) return -1;
// });

movements.sort((a, b) => a - b); // [-650, -400, -130, 70, 200, 450, 1300, 3000]
console.log(movements);

// Descending
// movements.sort((a, b) => {
//   if (a > b) return -1; // [3000, 1300, 450, 200, 70, -130, -400, -650]
//   if (a < b) return 1;
// });

movements.sort((a, b) => b - a); // [3000, 1300, 450, 200, 70, -130, -400, -650]
console.log(movements);

fill and from Method

fill() 메서드는 배열의 시작 인덱스부터 끝 인덱스의 이전까지 정적인 값 하나로 채웁니다.
Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.

const arr = [1, 2, 3, 4, 5, 6, 7];
console.log(new Array(1, 2, 3, 4, 5, 6, 7)); // [1, 2, 3, 4, 5, 6, 7]

//Empty arrays + fill method
const x = new Array(7);
console.log(x); // [empty × 7]
// console.log(x.map(() => 5));

x.fill(1, 3, 5);
x.fill(1);
console.log(x); // [1, 1, 1, 1, 1, 1, 1]

arr.fill(23, 2, 6);
console.log(arr); // [1, 2, 23, 23, 23, 23, 7]

// Array from
const y = Array.from({ length: 7 }, () => 1);
console.log(y); // [1, 1, 1, 1, 1, 1, 1]

const z = Array.from({ length: 7 }, (_, i) => i + 1);
console.log(z); // [1, 2, 3, 4, 5, 6, 7]

const dice = Array.from({ length: 100 }, () => Math.round(Math.random() * 6));
console.log(dice);

labelBalance.addEventListener(`click`<, function () {
  const movementsUI = Array.from(
    document.querySelectorAll(`.movements__value`),
    (el) => Number(el.textContent.replace(``, ``))
  );
  console.log(movementsUI); // [1300, 1300, 70, 70, -130, -130, -650, -650, 3000, 3000, -400, -400, 450, 450, 200, 200]

  const movementsUI2 = [...document.querySelectorAll(`.movements__value`)];
  console.log(movementsUI2);
});

Which Array Method to USE?

원래 배열을 변경하려면

  • Add to original:
    .push (end)
    .unshift (start)

  • Remove from original:
    .pop (end)
    .shift (start)
    .splice (any)

  • Others:
    .reverse
    .sort
    .fill

새로운 배열

  • Computed from original:
    .map (loop)

  • Filtered using condition:
    .filter

  • Portion of original:
    .slice

  • Adding original to other:
    .concat

  • Flattening the original:
    .flat
    .flatMap

배열 인덱스

  • Based on value:
    .indexOf

  • Based on test condition:
    .findIndex

배열 선택자

  • Based on test condition:
    .find

배열의 포함이 되어있는지 알고싶다면

  • Based on value:
    .includes

  • Based on test condition:
    .some
    .every

새로운 문자열

  • Based on separator string:
    .join

값을 바꾸고싶다면

  • Based on accumulator
    .reduce
    (배열을 단일로 요약 모든 유형의 값: 숫자,
    문자열, 부울 또는 새로운 배열 또는 객체)

배열을 반복하려면

  • Based on callback:
    .forEach
    (새 어레이를 생성하지 않고, 그냥 반복)

Array Methods Practice

// Array Methods Practice

// 1.
const bankDepositSum = accounts
  .flatMap((acc) => acc.movements)
  .filter((mov) => mov > 0)
  .reduce((sum, cur) => sum + cur, 0);
console.log(bankDepositSum); // 25180

// 2.
// filter Method
const numDeposit1000 = accounts
  .flatMap((acc) => acc.movements)
  .filter((mov) => mov >= 1000).length; // 6
console.log(numDeposit1000);

// reduce Method
const num2Deposit1000 = accounts
  .flatMap((acc) => acc.movements)
  .reduce((count, cur) => (cur >= 1000 ? ++count : count), 0); // 6
console.log(num2Deposit1000);

// ++연산자의 오류
let a = 10;
console.log(++a); // 11 (++연산자를 뒤에 배치할경우 10으로 출력됨)
console.log(a); // 11

// 3.
const { deposits, withdrawals } = accounts
  .flatMap((acc) => acc.movements)
  .reduce(
    (sums, cur) => {
      // cur > 0 ? (sums.deposit += cur) : (sums.withdarwals += cur);
      sums[cur > 0 ? `deposits` : `withdrawals`] += cur;
      return sums;
    },
    { deposits: 0, withdrawals: 0 }
  );

console.log(deposits, withdrawals); // 25180 -7340

// 4.
// this is a nice title => This Is a Nice Title
const convertTitleCase = function (title) {
  const capitalize = (str) => str[0].toUpperCase() + str.slice(1);
  const exceptions = [`a`, `an`, `the`, `and`, `but`, `or`, `on`, `in`, `with`];

  const titleCase = title
    .toLowerCase()
    .split(` `)
    .map((word) => (exceptions.includes(word) ? word : capitalize(word)))
    .join(` `);
  return capitalize(titleCase);
};

console.log(convertTitleCase(`this is a nice title`)); // This Is a Nice Title
console.log(convertTitleCase(`this is a LONG title but not too long`)); // This Is a Long Title but Not Too Long
console.log(convertTitleCase(`and here is another title with an EXAMPLE`)); // And Here Is Another Title with an Example

Coding Challenge #4

/* Coding Challenge #4 

줄리아와 케이트는 여전히 개를 연구하고 있으며, 이번에는 개가 너무 많이 먹거나 너무 적게 먹는지를 연구하고 있습니다.
너무 많이 먹는다는 것은 개의 현재 음식 섭취량이 권장량보다 큰 경우이고, 너무 적게 먹는다는 것은 그 반대입니다.
적절한 양을 먹는다는 것은 개의 현재 음식 섭취량이 권장량의 10% 위 아래로 범위 내에 있는 경우를 말합니다 (힌트 참조).

1. 'dogs'라는 개 객체를 포함하는 배열을 순환하며 각 개에 대해 권장 음식 섭취량을 계산하고 새로운 속성으로 객체에 추가해야 합니다. 새로운 배열을 생성하지 말고, 단순히 배열을 순환하십시오. 
공식은 다음과 같습니다: 권장 음식 섭취량 = 무게 ** 0.75 * 28 (결과는 음식의 그램 수이며, 무게는 kg로 표기되어야 합니다).

2. 사라의 개를 찾고, 그 개가 너무 많이 먹거나 너무 적게 먹는지 콘솔에 기록해야 합니다. 
힌트: 일부 개는 여러 주인을 가지고 있으므로, 먼저 소유자 배열에서 사라를 찾아야 합니다. 이 문제는 조금 복잡합니다 (의도적으로).

3. 너무 많이 먹는 개의 소유자를 포함하는 배열 ('ownersEatTooMuch')과 너무 적게 먹는 개의 소유자를 포함하는 배열 ('ownersEatTooLittle')을 생성해야 합니다.

4. 3번에서 생성된 각 배열에 대해 다음과 같은 형식으로 콘솔에 문자열을 기록해야 합니다: "Matilda and Alice and Bob의 개는 너무 많이 먹습니다!" 그리고 "Sarah and John and Michael의 개는 너무 적게 먹습니다!"

5. 권장 음식 섭취량과 정확히 같은 양을 먹는 개가 있는지 콘솔에 기록해야 합니다. (true 또는 false로만)

6. 적절한 양의 음식을 먹는 개가 있는지 콘솔에 기록해야 합니다. (true 또는 false로만)

7. 적절한 양의 음식을 먹고 있는 개를 포함하는 배열을 생성해야 합니다. (6번에서 사용한 조건을 재사용하려고 합니다.)

8. 'dogs' 배열의 얕은 복사본을 생성하고, 권장 음식 섭취량을 기준으로 오름차순으로 정렬해야 합니다. (음식 섭취량은 배열의 객체 내에 있음을 유념하세요.)

Hint: 
1. 챌린지를 해결하기 위해 다양한 도구와 함수를 활용할 수 있습니다. 

2. 권장 음식 섭취량의 10% 범위 내에 있다는 것은 다음과 같습니다: current > (recommended * 0.90) && current < (recommended * 1.10). 
즉, 현재 섭취량은 권장 섭취량의 90%와 110% 사이여야 합니다. 기본적으로 현재 섭취량은 권장 섭취량의 90% 이상 110% 이하여야 합니다. */

const dogs = [
  { weight: 22, curFood: 250, owners: ["Alice", "Bob"] },
  { weight: 8, curFood: 200, owners: ["Matilda"] },
  { weight: 13, curFood: 275, owners: ["Sarah", "John"] },
  { weight: 32, curFood: 340, owners: ["Michael"] },
];

// 1.
dogs.forEach((dog) => (dog.recFood = Math.trunc(dog.weight ** 0.75 * 28)));

console.log(dogs); /*
0: {weight: 22, curFood: 250, owners: Array(2), recFood: 284}
1: {weight: 8, curFood: 200, owners: Array(1), recFood: 133}
2: {weight: 13, curFood: 275, owners: Array(2), recFood: 191}
3: {weight: 32, curFood: 340, owners: Array(1), recFood: 376} */

// 2.
const dogSarah = dogs.find((dog) => dog.owners.includes(`Sarah`));

console.log(dogSarah); /*
{weight: 13, curFood: 275, owners: Array(2), recFood: 191}
curFood: 275
owners: (2) ['Sarah', 'John']
recFood: 191
weight: 13 */
console.log(
  `Sarah's dog is eating too ${
    dogSarah.curFood > dogSarah.recFood ? `much` : `Little`
  }`
); // Sarah's dog is eating too much

// 3.
const ownersEatTooMuch = dogs
  .filter((dog) => dog.curFood > dog.recFood)
  .flatMap((dog) => dog.owners);
const ownersEatTooLittle = dogs
  .filter((dog) => dog.curFood < dog.recFood)
  .flatMap((dog) => dog.owners);

console.log(ownersEatTooMuch); //['Matilda', 'Sarah', 'John']

console.log(ownersEatTooLittle); //['Alice', 'Bob', 'Michael']

// 4.
console.log(`${ownersEatTooMuch.join(` and `)}'s dogs eat too much!"`);
console.log(`${ownersEatTooLittle.join(` and `)}'s dogs eat too little!"`);

// 5.
console.log(dogs.some((dog) => dog.curFood === dog.recFood)); // false (some Method 같은경우는 하나라도 조건에 만족하면 true를 출력)

// 6.
const checkEatingOkay = (dog) =>
  dog.curFood > dog.recFood * 0.9 && dog.curFood < dog.recFood * 1.1;

console.log(dogs.some(checkEatingOkay)); // true

// 7.
console.log(dogs.filter(checkEatingOkay)); // {weight: 32, curFood: 340, owners: ['Michael'], recFood: 376}

// 8.
const dogsSorted = dogs.slice().sort((a, b) => a.recFood - b.recFood);

console.log(dogsSorted);
/*
0: {weight: 8, curFood: 200, owners: Array(1), recFood: 133}  (recFood가 오름차순으로 정렬)
1: {weight: 13, curFood: 275, owners: Array(2), recFood: 191}
2: {weight: 22, curFood: 250, owners: Array(2), recFood: 284}
3: {weight: 32, curFood: 340, owners: Array(1), recFood: 376}*/

MDN Reference

findIndex Method
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

some and every Method
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/some
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/every

fill and from Method
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

flat and flatMap Method
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

0개의 댓글