Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 객체의 숫자 값을 특정 범위로 정규화하는 방법

문제 소개

다음과 같이 문자열 키에 숫자 값이 매핑되어 있는 객체가 있다고 가정해 보겠습니다.

const obj = {
    num1: 45,
    num2: 78,
    num3: 234,
    num4: 3,
    num5: 79,
    num6: 23
};

우리가 작성해야 할 함수는 이런 객체를 첫 번째 인수로, 그리고 반드시 두 개의 숫자를 담은 배열을 두 번째 인수로 받습니다.

두 번째 인수는 하나의 범위(range)를 의미합니다.

[a, b] (b >= a)

즉, 객체의 모든 값을 이 범위 안으로 정규화(normalize)하는 것이 목표입니다. 객체에서 가장 큰 값은 b가 되고, 가장 작은 값은 a가 되며, 나머지 값들은 최솟값과 최댓값 사이에서의 상대적 위치를 유지한 채 비례하여 조정되어야 합니다.

정규화 원리

값을 새로운 범위로 선형 변환할 때 널리 쓰이는 공식은 다음과 같습니다.

새 값 = a + ((원래 값 − 최솟값) × (b − a) ÷ (최댓값 − 최솟값))

(원래 값 − 최솟값)이 0부터 (최댓값 − 최솟값) 사이의 상대 거리를 나타내고, 여기에 새 범위 폭과 원래 폭의 비율인 (b − a) ÷ (최댓값 − 최솟값)을 곱한 뒤 a를 더하면 새로운 범위에 맞는 값이 됩니다.

예제 코드

const obj = {
    num1: 45,
    num2: 78,
    num3: 234,
    num4: 3,
    num5: 79,
    num6: 23
};
const range = [10, 15];
const normaliseObject = (obj, range) => {
    const values = Object.values(obj);
    const min = Math.min.apply(Math, values);
    const max = Math.max.apply(Math, values);
    const variation = (range[1] - range[0]) / (max - min);
    Object.keys(obj).forEach(el => {
        const val = (range[0] + ((obj[el] - min) * variation)).toFixed(2);
        obj[el] = +val;
    });
};
normaliseObject(obj, range);
console.log(obj);

코드 설명

  • Object.values(obj) : 객체의 모든 값을 배열 형태로 꺼내옵니다.
  • Math.min.apply / Math.max.apply : 배열 전체에서 최솟값(3)과 최댓값(234)을 구합니다.
  • variation : 새 범위의 폭(15 − 10 = 5)을 원래 데이터의 폭(234 − 3 = 231)으로 나눈 배율입니다.
  • toFixed(2)와 단항 연산자 + : 결과를 소수점 둘째 자리까지 반올림한 문자열로 만든 후, 다시 숫자로 변환하여 저장합니다.

실행 결과

콘솔에는 다음과 같은 출력이 나타납니다.

{
    num1: 10.91,
    num2: 11.62,
    num3: 15,
    num4: 10,
    num5: 11.65,
    num6: 10.43
}

가장 작았던 num4(3)는 범위의 하한인 10으로, 가장 컸던 num3(234)는 상한인 15로 변환되었습니다. 나머지 값들도 기존의 크기 순서를 그대로 유지하면서 10과 15 사이에 배치된 것을 확인할 수 있습니다.