programing

세그먼트에 숫자를 제한하는 가장 우아한 방법은 무엇입니까?

newsource 2023. 8. 8. 21:40

세그먼트에 숫자를 제한하는 가장 우아한 방법은 무엇입니까?

예를 들어x,a그리고.b숫자입니다.제한해야 합니다.x그 분야의 범위까지.[a, b].

즉, 클램프 기능이 필요합니다.

clamp(x) = max( a, min(x, b) )

누가 좀 더 읽기 쉬운 버전을 생각해 낼 수 있습니까?

당신이 그것을 하는 방법은 꽤 일반적입니다.유틸리티를 정의할 수 있습니다.clamp함수:

/**
 * Returns a number whose value is limited to the given range.
 *
 * Example: limit the output of this computation to between 0 and 255
 * (x * 255).clamp(0, 255)
 *
 * @param {Number} min The lower boundary of the output range
 * @param {Number} max The upper boundary of the output range
 * @returns A number in the range [min, max]
 * @type Number
 */
Number.prototype.clamp = function(min, max) {
  return Math.min(Math.max(this, min), max);
};

(비록 언어 기본 제공 기능을 확장하는 것은 일반적으로 눈살을 찌푸리게 하지만)

덜 "수학" 지향적인 접근법이지만, 이러한 방식으로 작동해야 합니다.</>테스트는 노출되지만(최소화보다 더 이해하기 쉬울 수 있음) 실제로는 "읽을 수 있는" 의미에 따라 다릅니다.

function clamp(num, min, max) {
  return num <= min 
    ? min 
    : num >= max 
      ? max 
      : num
}

빌트인에 추가할 제안이 있습니다.Math이 작업에 대한 반대:

Math.clamp(x, lower, upper)

하지만 오늘부로 1단계 제안입니다.광범위하게 지원될 때까지(보장되지 않음) 폴리필을 사용할 수 있습니다.

간단한 방법은 다음과 같습니다.

Math.max(min, Math.min(number, max));

그리고 당신은 이것을 감싸는 함수를 분명히 정의할 수 있습니다.

function clamp(number, min, max) {
  return Math.max(min, Math.min(number, max));
}

원래 이 답변은 위의 기능도 글로벌에 추가했습니다.Math물체, 하지만 그것은 지나간 시대의 유물이기 때문에 제거되었습니다(제안에 대해 @Aurelio 감사합니다.

이는 "라이브러리만 사용"하는 답변이 아니라 Lodash를 사용하는 경우에만 사용할 수 있습니다.

_.clamp(yourInput, lowerBound, upperBound);

그래서:

_.clamp(22, -10, 10); // => 10

다음은 Lodash 소스에서 가져온 구현입니다.

/**
 * The base implementation of `_.clamp` which doesn't coerce arguments.
 *
 * @private
 * @param {number} number The number to clamp.
 * @param {number} [lower] The lower bound.
 * @param {number} upper The upper bound.
 * @returns {number} Returns the clamped number.
 */
function baseClamp(number, lower, upper) {
  if (number === number) {
    if (upper !== undefined) {
      number = number <= upper ? number : upper;
    }
    if (lower !== undefined) {
      number = number >= lower ? number : lower;
    }
  }
  return number;
}

또한 Lodash는 단일 메소드를 독립 실행형 모듈로 사용할 수 있으므로 이 메소드만 필요한 경우 라이브러리의 나머지 부분 없이 설치할 수 있습니다.

npm i --save lodash.clamp

es6 화살표 기능을 사용할 수 있는 경우 부분 응용 프로그램 접근 방식을 사용할 수도 있습니다.

const clamp = (min, max) => (value) =>
    value < min ? min : value > max ? max : value;

clamp(2, 9)(8); // 8
clamp(2, 9)(1); // 2
clamp(2, 9)(10); // 9

or

const clamp2to9 = clamp(2, 9);
clamp2to9(8); // 8
clamp2to9(1); // 2
clamp2to9(10); // 9

함수를 정의하지 않으려면 다음과 같이 작성합니다.Math.min(Math.max(x, a), b)나쁘지 않아요.

이렇게 하면 최소화된 3차 옵션이 3차 옵션과 동일하지만 가독성을 희생하지 않는 경우로 확장됩니다.

const clamp = (value, min, max) => {
  if (value < min) return min;
  if (value > max) return max;
  return value;
}

35b(사용하는 경우 43b)로 최소화function):

const clamp=(c,a,l)=>c<a?a:c>l?l:c;

또한 사용하는 성능 툴링 또는 브라우저에 따라 Math 기반 구현 또는 Ternary 기반 구현이 더 빠르다는 다양한 결과를 얻을 수 있습니다.거의 동일한 성능의 경우 가독성을 선택할 것입니다.

화살표 섹시함의 정신에서 정지 매개변수를 사용하여 마이크로 클램프/제약조건/게이트/&c. 함수를 생성할 수 있습니다.

var clamp = (...v) => v.sort((a,b) => a-b)[1];

그런 다음 세 개의 값을 전달합니다.

clamp(100,-3,someVar);

즉, 섹시하다는 것은 '짧다'는 뜻입니다.

내가 가장 좋아하는 것:

[min,x,max].sort()[1]

언급URL : https://stackoverflow.com/questions/11409895/whats-the-most-elegant-way-to-cap-a-number-to-a-segment