JavaScript에서의 골프 팁


133

JavaScript에서 골프를 치기위한 일반적인 팁은 무엇입니까? JavaScript와 관련이있는 코드 골프 문제에 일반적으로 적용 할 수있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).

참고 : ECMAScript 6 이상의 골프 팁 도 참조하십시오 .


실제로 궁금합니다. 글로벌 (저장 var) 에 변수를 넣을 수 있습니까? 그리고 JavaScript 골프 코드는 함수이거나 직접 출력해야합니까? 솔직히 이것이 큰 차이를 만들 수 있다고 생각합니다.
pimvdb

1
@primvdb : 허용되지만 함수가 여러 번 호출되고 전역 변수를 조작하거나 재귀 함수 인 경우 부작용을 일으킬 수 있으므로주의해야합니다.
mellamokb

답변:


108

팬시 포 루프

비표준 방식으로 표준 for 루프를 사용할 수 있습니다

for ( a; b; c )

본질적으로 다음과 같습니다.

a;
while ( b )
{
  ...
  c;
}

따라서 좋은 방법은 while루프로 코드를 작성한 다음 루프의 a,b,c일부로 코드 를 분할하는 것 for입니다.

내가 쓴 몇 가지 예 :

for(x=y=n;!z;x--,y++)z=i(x)?x:i(y)?y:0
for(a=b=1;b<n;c=a+b,a=b,b=c);

세터 연결

여러 값을 초기화하거나 재설정하는 경우 값을 필요한 모든 변수에 연결하십시오.

a=b=1;

암시 적 캐스팅

유형을 확인하지 말고 그대로 사용하십시오. parseInt()비용 10문자. 끈에서 캐스트해야하는 경우 창의력을 발휘하십시오.

a='30';
b='10';
c = a + b; //failure
c = parseInt(a) + parseInt(b) //too long

c = -(-a-b); //try these
c = ~~a+~~b;
c = +a+ +b;
c = a- -b;

세미콜론을 피하십시오

JavaScript에는 자동 세미콜론 삽입이 있습니다. 자주 사용하십시오.

원 라이너

가능한 한 줄이나 매개 변수로 밀어 넣어 괄호를 절약하십시오.

a( realParam1, realParam2, fizz='buzz' )

증가 / 감소 연산자

a = a - 1;
foo(a);

foo(a);
a = a - 1;

쉽게 다시 쓸 수 있습니다

foo(--a);

foo(a--);

각기.

글로벌 컨텍스트에서 this또는 self대신 사용window

자기 설명 2 문자 절약.

반복 속성 액세스에 대괄호 표기법 사용

이것은 속성 이름 길이와 액세스 횟수 간의 균형을 맞추는 행위입니다. a.longFunctionName()점 표기법으로 두 번 호출 하는 대신 이름을 저장하고 대괄호 표기법으로 함수를 호출하는 것이 더 짧습니다.

a.longFunctionName(b)
a.longFunctionName(c)
//42

-vs-

a[f='longFunctionName'](b)
a[f](c)
//34

이것은 document.getElementById로 줄일 수있는 기능에 특히 효과적입니다 d[e].

노트 :

대괄호 표기법으로 비용은 6 + name.length처음 문자입니다. 각 후속 액세스에는 3문자 비용이 있습니다.

점 표기법의 경우 모든 액세스 비용 name.length + 1.문자 (+1 )입니다.

이 경우이 방법을 사용하십시오 6 + name.length + (3 * (accesses - 1)) < accesses * (name.length + 1).

len = 속성 이름 길이
i = 활용하기위한 최소 액세스

len | i 
========
1   |  
2   |  
3   | 7 
4   | 4 
5   | 3 
6   | 3 
7   | 3 
8+  | 2 

액세스 수는 여러 개체에 걸쳐있을 수도 있습니다. .length다른 배열에서 4 번 이상 액세스 하면 string을 보유한 동일한 변수를 사용할 수 있습니다 'length'.


5
c = ~~a-~~b이어야합니다 c = ~~a+~~b. 또한, 암시 적으로 사용하여 정수로 캐스트 할 수 있습니다 |0예를 들어, Math.random()*6|0.
mellamokb 2016 년

7
단항 더하기 연산자로 문자열을 숫자로 강제 변환하는 것이 더 저렴합니다. ab문자열 인 경우 +a+b숫자로 변환하여 추가 할 수 있습니다.
피터 올슨

8
내가 사용하는거야 맹세 d- -b언젠가는 내 코드에 ...
존 드보락

4
+ a + b가 작동하지 않습니다 (적어도 나의 경우 ...) // a = "1", b = "1", + a + b // "11"제공
imma

2
동일한 객체 에서 함수를 두 번 이상 사용하는 경우 "반복 함수 호출에 Array-Access 사용"의 경우 조금 더 짧은 것은 다음과 같은 새 멤버에 함수를 지정하는 것입니다.a.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
Martin Ender


56

쉼표 연산자를 사용하여 중괄호를 피하십시오 ( C 에도 적용됨 ).

if(i<10)m+=5,n-=3;

대신에

if(i<10){m+=5;n-=3}

한 글자 더 깁니다.


2
첫 번째 샘플의 끝에 세미콜론이 필요합니까?
wjl

4
@ wjlafrance : 원 라이너 끝에있는 경우에만 필요하지 않습니다.
mellamokb

48

더 짧은 난수 생성

임의의 부울 ( 0또는 1) 이 필요한 경우 :

new Date&1 // equivalent to Math.random()<0.5

임의의 정수가 필요한 경우 0 <= n < 1337:

new Date%1337 // equivalent to Math.floor(Math.random()*1337))

이것은 Date에포크 이후 밀리 초의 양으로 JavaScript에 내부적으로 저장되어 있기 때문에 작동하므로 정수 수학을 시도 할 때 new Date강제로 진행 123somebignumber456됩니다.

물론,이 "무작위"숫자는 실제로 임의적이지 않습니다. 특히 연속해서 여러 번 연속해서 호출하는 경우 명심하십시오.


1
프로그래머가 시간에 대해 더 많은 허위 사실 을 읽는 동안이 대답을 기억했습니다 . “21. 서로 바로 옆에 두 개의 날짜 개체를 만들면 같은 시간을 나타냅니다. (환상적인 Heisenbug 생성기)” .
세바스찬 시몬

39

키워드 사용을 피하기 위해 객체 리터럴 형태의 get / set을 사용할 수 있습니다 function.

var obj = {
  get f(){
    console.log("just accessing this variable runs this code");
    return "this is actually a function";
  },
  set f(v){
    console.log("you can do whatever you want in here, passed: " + v);
  }
};

1 && obj.f; // runs obj.[[get f]]
obj.f = Infinity; // runs obj.[[set f]](Infinity)

게터 / 세터 부분이 정말 도움이되었습니다. thx
gion_13

1
실제로 <= 2 번만 사용하는 경우 객체 방법이 훨씬 좋습니다. 반면, 화살표 기능은 거의 같은 목적으로 사용되므로 문자를 자르는 데 훨씬 효과적이며 클래스는 골프 코드에서 거의 유용하지 않습니다.
Isiah Meadows

지원이 중요한 경우 fx에서는 화살표 기능이 지원되지 않습니다. ie11
Jim Wolff

35

이것은 덜 알려지고 덜 사용되지만 올바른 상황에서 사용하면 인상적 일 수 있습니다. 인수를 취하지 않고 호출 될 때 항상 다른 숫자를 반환하는 함수를 고려하면 반환 된 숫자가 계산에 사용됩니다.

var a = [ 
    Math.random()*12|0,
    Math.random()*11|0,
    Math.random()*10|0,
    /* etc... */ 
];

일반적으로 단일 문자 변수 이름을 사용하여이 기능을 단축 할 수 있습니다.

var r=Math.random,a=[r()*12|0,r()*11|0,r()*10|0,r()*9|0,r()*8|0,r()*7|0,r()*6|0,r()*5|0];

길이를 줄이는 더 좋은 방법은 abusing valueOf을 사용하여 호출 당 2자를 절약 할 수 있습니다. 함수를 5 번 이상 호출하면 유용합니다.

var r={valueOf:Math.random},a=[r*12|0,r*11|0,r*10|0,r*9|0r*8|0,r*7|0,r*6|0,r*5|0];

8
또는 다음 중 하나와 같이 수행 할 수 있습니다. let a=[5,6,7,8,9,10,11,12].map(x=>x*Math.random()|0)또는 let a=Array(7).map((_,i)=>i*Math.random()|0+5)36 또는 42 바이트가 각각 저장됩니다.
Isiah Meadows 2019

교체 r()하거나 더 짧게 만들 수 있습니까?
NiCk Newman

3
r={valueOf:Math.random}그것은 천재입니다. : D
ETHproductions

1
@Isiah, 그래, 넌 지금 할 수있어 :-D
Andy E

32

단락 연산자 활용

if문장이나 삼항 연산자를 사용하는 대신 코드를 사용 &&하고 ||단축 할 수 있습니다. 예를 들어 :

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;

될 수있다

var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);

return match && decodeURIComponent(match[1].replace(/\+/g, ' '));

||연산자는 종종 기본값을 설정하기위한 이러한 방법으로 사용된다 :

evt = evt || window.event;

이것은 글쓰기와 같습니다

if (!evt)
    evt = window.event;

Array를 사용하여 반복적 인 문자열 만들기

특정 문자의 긴 문자열을 초기화하려면 길이가 n + 1 인 배열을 작성하면됩니다 . 여기서 n 은 문자를 반복하려는 횟수입니다.

// Create a string with 30 spaces
str = "                              ";

// or
str = Array(31).join(" ");

줄이 클수록 절약 효과도 커집니다.

파싱 ​​번호

사용 +하고 ~대신 운영자 parseFloat()또는 parseInt()인 문자열 유형 병합 할 때 단지 숫자 숫자 유형을 :

var num = "12.6";
parseFloat(num) === +num;  // + is 10 characters shorter than parseFloat()

var num2 = "12"
parseInt(num2) === +num2;   // + is 8 characters shorter than parseInt()

var num3 = "12.6"
parseInt(num3) === ~~num3;  // ~~ is 7 characters shorter than parseInt()

var num4 = "12.6"
parseInt(num4) === num4|0;  // |0 is 7 characters shorter than parseInt()

하지만주의하십시오, 다른 유형 (예를 들어, 이러한 연산자와 합체 할 수있다 true될 것 1빈 문자열 또는 문자열이 그냥 흰색 공간이 될 것 포함) 0. 그러나 특정 상황에서는 유용 할 수 있습니다.


6
Array를 사용하여 반복적 인 문자열을 만들기위한 +1-그것에 대해 생각하지 않았습니다.
mellamokb 2016 년

4
반복적 인 문자열을 만들려면 ES6에서 다음을 사용할 수 있습니다.str.repeat(count)
Oriol

26

사용자 입력을 얻기 위해 prompt () 호출로 변수 초기화 몰래

n=prompt(i=5);     // sets i=5 at the same time as getting user input

사용하는 대신

n=prompt();i=5;

부작용으로 1 문자를 저장하는 동안 프롬프트 창에 입력 값을 표시합니다.


12
인수를 허용하지 않는 함수에도 적용 할 수 있습니다.
Casey Chu

3
함수가 인수를 허용하더라도 [1,2,3].join('',i=5)중괄호 쌍을 저장하는 경우 와 같이 유용 할 수 있습니다 .
DocMax

3
@DocMax : 쉼표 연산자를 사용할 수 있습니다 i=5,[1,2,3].join().
Konrad Borowski 2019 년

@GlitchMr : 할 수는 있지만 문자를 저장하지는 않습니다. 나는 대부분의 시간이 더 깨끗할 것이라는 데 동의합니다. 나는 지금 주문을 할 수는 없지만 내 주문으로 문자를 절약 할 수있는 경우가 여전히있을 수 있다고 생각합니다 (그리고 잘못되었을 수도 있습니다).
DocMax

@DocMax ASI를 활용하는 경우에만 해당됩니다.
Isiah Meadows 2018

24

중첩 된 for 루프를 결합하십시오.

// before:
for(i=5;i--;)for(j=5;j--;)dosomething(i,j)

// after:
for(i=25;i--;)dosomething(0|i/5,i%5)

i/ 값이 다른 예 j:

// before:
for(i=4;i--;)for(j=7;j--;)dosomething(i,j)

// after:
for(i=28;i--;)dosomething(0|i/7,i%7)

사소한 오타이지만 매우 영리합니다! 이것은 길이가 같은 중첩 루프에서만 작동합니다 (잘못되지 않은 경우).
Camilo Martin

1
@CamiloMartin 아니오, 루프의 길이가 같을 필요는 없습니다. 반복의 결과 숫자는 i*j상기 분할 / 모듈러스 연산자의 개별 값을 검색 i하고 j.
quietmint

@ user113215 당신 말이 맞아요! :) 예제를 포함하도록 답변을 편집했습니다.
Camilo Martin

23

유니 코드 단축키

큰 골프 도전에서 빌트인 속성의 지옥을 사용하는 경우 모든 속성의 별칭을 한 문자로 지정할 수 있습니다.

[Math,Number,S=String,Array].map(b=>
    Object.getOwnPropertyNames(b).map((p,i)=>
        b.prototype[S.fromCharCode(i+248)]=b[p]
    )
)

위의 코드를 실행하면 다음과 같이 사용할 수 있습니다.
"foo".Č(/.*/,'bar') // replaces foo with bar

이 비용은 118 바이트이므로 특정 상황에서는 유용하지 않을 수 있습니다.

브라우저에 따라 다를 수 있으며 with(Array){join(foo),...}변수가 사용 속성으로 짧 거나 정의되어 있는지 확실하지 with(Array){j=join,m=map...}않지만 여전히 언급 할 가치가 있습니다.

    Math        Number              String              Array

ø   toSource    prototype           prototype           prototype
ù   abs         NaN                 quote               join
ú   acos        POSITIVE_INFINITY   substring           reverse
û   asin        NEGATIVE_INFINITY   toLowerCase         sort
ü   atan        MAX_VALUE           toUpperCase         push
ý   atan2       MIN_VALUE           charAt              pop
þ   ceil        MAX_SAFE_INTEGER    charCodeAt          shift
ÿ   clz32       MIN_SAFE_INTEGER    contains            unshift
Ā   cos         EPSILON             indexOf             splice
ā   exp         isFinite            lastIndexOf         concat
Ă   floor       isInteger           startsWith          slice
ă   imul        isNaN               endsWith            filter
Ą   fround      toInteger           trim                isArray
ą   log         parseFloat          trimLeft            lastIndexOf
Ć   max         parseInt            trimRight           indexOf
ć   min         length              toLocaleLowerCase   forEach
Ĉ   pow         name                toLocaleUpperCase   map
ĉ   random      arguments           normalize           every
Ċ   round       caller              match               some
ċ   sin                             search              reduce
Č   sqrt                            replace             reduceRight
č   tan                             split   
Ď   log10                           substr  
ď   log2                            concat  
Đ   log1p                           slice   
đ   expm1                           fromCharCode    
Ē   cosh                            fromCodePoint   
ē   sinh                            localeCompare   
Ĕ   tanh                            length  
ĕ   acosh                           name    
Ė   asinh                           arguments   
ė   atanh                           caller  
Ę   hypot           
ę   trunc           
Ě   sign            
ě   cbrt            
Ĝ   E           
ĝ   LOG2E           
Ğ   LOG10E          
ğ   LN2         
Ġ   LN10            
ġ   PI          
Ģ   SQRT2           
ģ   SQRT1_2         

Google 크롬을 사용하고 있으며 모두 정의되지 않았습니다.
SuperJedi224

매우 파이어 폭스 전용이어야합니다. 불편을 드려 죄송합니다.
bebe

왜이 모든 특수 문자입니까? 왜 인쇄 가능한 ASCII를 사용하지 않습니까? (타이핑하기 쉽고, 더 안정적이며, 골프를 위해 1 바이트 만)
Cyoce

속성 Math이 없기 때문에 실제로 작동 하지 않습니다 .prototype. 그러나을 제거 Math하면이를 1 바이트 문자에 할당하는 114 바이트 스 니펫으로 골프를 쳤습니다. 여기에서 찾을 수 있습니다 .
ETHproductions

1
당신은 또한 골프 범위로 모든 속성을 이동시키는 비용으로 106 바이트 내 용액 À- ÿ여전히 (JS 지원)을 ISO-8859-1 인코딩 각각 1 바이트이다. Firefox 50에서는 불행히도이 .localeCompare방법을 사용 ×하지만 일반적으로 문제가되지는 않습니다. 출처
ETHproductions

22

while루프를 루프로 변환하는 for것은 종종 동일합니다.

while(i--);
for(;i--;);

그러나 두 번째 형식은 변수 초기화를 결합 할 수 있습니다.

i=10;while(i--);
for(i=10;i--;);

두 번째 형식은 첫 번째 형식보다 한 문자가 짧습니다.


6
또는 더 나은 방법은 for 루프를 사용하는 것입니다. 내가 경험 한 한 for 루프를 사용하여 더 큰 코드를 생성하는 경우는 실제로 없습니다.
Isiah Meadows 2019

22

예외 남용

문자열 / 문자 리터럴이 금지 된 경우 try catch 블록을 사용할 수 있습니다.

try{something0}catch(e){str=e.message.split(0)[0]}

지금 str과 동일"something"

더 많은 문자열이 필요한 경우 숫자로 묶을 수 있습니다 (예 : 0)

try{something0foo0bar0}catch(e){arr=e.message.split(0)}

지금 arr과 동일["something", "foo", "bar", " is not defined"]


18

당신이 변수를 초기화하는 경우 1처럼, (내부 루프에 대한 외부 루프에서 변수를 재설정, 예를 들어) 루프의 모든 반복에 (에서 다음과 같은 내 대답이 질문에 ) :

for(j=n-2;p=1,j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^

조건의 결과 j++<=n1항상 참이므로 조건을 변수에 직접 할당 할 수 있습니다 (거짓이되면 루프 실행이 중지되고 더 이상 문제가되지 않음).

for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;
          ^^^^^^^^

이 방법을 사용하면 일반적으로 2자를 저장할 수 있습니다 . @ugoren해당 답변에 대한 의견의 아이디어를 존중합니다 .


또 다른 예를 들어, 외부 for 루프 의 표현식 으로 여기 에이 트릭을 적용 w=r=++c<S.length하여 총 4자를 절약했습니다.


18

Spidermonkey (현재) 특정 스크립트를 승인 할 수있는 경우 ECMAScript 6 화살표 기능을 사용할 수 있습니다 . 다음과 같은 코드를 작성하는 대신.

a.map(function(x){return x*2}) // function? return?

이렇게 짧게 만들 수 있습니다.

a.map(x=>x*2)

17

당신은 사용하지 않는, NaN를 확인해야하는 경우 isNaN(x)만 사용 x!=x짧고도 작동합니다.

if(isNaN(x)){
if(x!=x){

이 경우에만 작동합니다 typeof(x) === "number". 예를 들어 문자열이면을 isNaN("string")반환 true하지만을 "string" != "string"반환합니다 false. 이것을 지적 해준 Cyoce에게 감사드립니다!


2
그것은이 기발한 것을 천재로 사용합니다. +1
ETHproductions

경고 : 이것들은 항상 동등한 것은 아닙니다 : isNaN("string")returns true, 반면에 "string"!="string"returns false(명백하게)
Cyoce

@Cyoce 좋은 지적, 감사합니다! 내 답변을 편집했습니다.
ProgramFOX

많은 경우 명시 적으로 if(!x){감지하는 경우 에도 갈 수 있습니다 NaN.
Hohmannfan

1
xnumber (으)로 캐스팅하면와 +x!=+x같지만 isNaN(x)여전히 2 자 더 짧습니다. 그런 다음 +"string"!=+"string"true를 반환합니다.
Tomas Langkaas

15

배열 합 / 곱 / 몫

ES5 : 17 바이트

eval(a.join('+'))

ES6 : 15 바이트

eval(a.join`+`)

물론 제품이나 지수 +등 원하는 것을 바꿀 수 있습니다 .*/


14

비트 연산을 사용하여 숫자를 0으로 반올림하십시오.

// do this
T=Math.random()*6+1|0

// or do this
T=~~(Math.random()*6+1)

(출처 : 랜덤 주사위 팁 )

연산자 우선 순위 에 따라 프로그램에서 더 짧은 것이 결정됩니다.


2
이것은 또한 문자열 입력을 정수로 통합하는 데 사용될 수 있습니다 n=prompt()|0.
mellamokb

1
bitwise는 math.floor와 비교할 때도 매우 빠릅니다 : jsperf.com/floor-vs-bitwise
vsync

@vsync : 이상합니다. Chrome 11.0.696.77에서 math.floor가 비트 단위로 약 두 배 빠릅니다.
mellamokb 2016 년

엄청 이상해. 나를 위해 그들은 Chrome에서 다소 속도가 같고 빠릅니다. 그러나 FF에서는 비트 단위가 Chrome보다 훨씬 빠르며 매우 Math.floor느립니다. 거의 사용해서는 안됩니다.
vsync

주석을 최신 상태로 유지하기 위해 현재 Fx에서는 빠르며 거의 동일합니다. 주변 코드와 비교할 때 처음에는 병목 현상이 발생하지 않을 것입니다 ...
FireFly

14

루핑 팁 I

마지막으로 사용한 시간 1을 변경하여 루핑 할 때 문자 를 저장할 수 있습니다 i.

//not so god
for(i=0;i<3;i++){
  alert(i);
}

//best
for(i=0;i<3;){
  alert(i++);
}

참고 :-- 너무 작동 하지만 무한 반복을 피하려면 루프를 적절히 수정하십시오.


루핑 팁 II

증분 연산자와 값으로 재생하여 하나의 문자를 저장할 수있는 특정 시나리오가 있습니다.

for(i=0;i++<9;)
for(i=0;++i<10;)

참고 : 예를 들어주의를 기울여야 0 to -1합니다. 그리고 9 to 10, 99 to 100, 그래서 주위까지 재생 문자를 저장하는 방법을 찾아


13

정수 ^대신 !=또는 ==정수와 비교할 때 사용

//x!=3?a:b
  x^3?a:b

//x==3?a:b
  x^3?b:a

내장 수학 함수에 대한 호출을 더 짧은 표현식으로 대체

//Math.ceil(n)
  n%1?-~n:n

//Math.floor(n)
  ~~n
  0|n

//Math.abs(n)
  n<0?-n:n

//Math.round(n)
  n+.5|0

//Math.min(x,y)
  x<y?x:y

//Math.max(x,y)
  y<x?x:y

2
또는 정수 -대신 간단하게 사용할 수 있습니다 !=. 예를 들어 n!=1?a:b다음과 같습니다.n-1?a:b
vrugtehagel

10

주목해야 할 것은 일부 인스턴스에서 0 대신 문자열을 사용하여 여기 저기에서 몇 바이트를 루프로 저장할 수 있다는 것입니다.

s='';for(i=0;i++<9;)s+=i
for(i=s='';i++<9;)s+=i
// s="123456789", i=10

1
나는 콘솔에서 ""++를 시도해 보았을 지 궁금해 할 것이다. 물론 변수에 먼저 있어야한다. 감사!
Vartan

10

아주 간단한 것도, 아무도 언급하지 않았습니다.

사용 중이 Math.min()거나 Math.max()다음을 수행하여 6자를 저장할 수 있습니다.

Math.min(a,b)  // 13 chars
a<b?a:b        //  7 chars

Math.max(a,b)
a>b?a:b

10

반올림

대안 Math.floor()이 게시 된 것을 알고 있지만 다른 것은 어떻습니까?

바닥:

Math.floor(x) //before
0|x           //after

반올림 :

Math.round(x) //before
0|x+.5        //after

천장:

Math.ceil(x) //before
x%1?-~x:x    //after - credits to @Tomas Langkaas

1
참고 0|x+1당신의 천장을 발견 할 수는 이미 정수의 경우 단순히 1을 추가합니다. (대부분의) 안전한 대안은 0|x+1-1e9이지만 이것은 3 바이트 더 짧습니다.
ETHproductions

@ETHproductions은 무슨 뜻 0|x+1-1e-9인가요?
Mama Fun Roll 1

네 지적 해 주셔서 감사합니다. (어떤 이유로 @ (사용자 이름)을 할 수 없습니다 ...)
ETHproductions

아마 내 사용자 이름 문자가 거꾸로 있기 때문에 :)
Mama Fun Roll 1

1
천장의 경우 x%1?-~x:x(9 자)가 더 나은 대안입니다. 그러나 바닥재 대안 0|x및과 마찬가지로 ~~x양수에만 적용됩니다.
Tomas Langkaas

9

삼항 연산자를 사용하여 두 숫자 중에서 선택 하고 조건이 부울 또는 숫자 인 1 or 0 경우 대신 수학 연산을 수행 할 수 있습니다.

(x ? num1 : num2) conclusions:

    1)if num1 equals num2, there ARE savings
    2)if num1 is (+1) or (-1) than num2, there ARE savings
    3)if either num1 or num2 equals to 0, there ARE savings
    4)it is MORE LIKELY to find greater savings on num1>num2 instead of num1<num2
    5)in method (*A) and (*B), savings are NOT GUARANTEED

    a)num1>num2
        i)(num1==(num2+1))
            ex1: (x?5:4) to (x+4)
            ex2: (x?8:7) to (x+7)
        ii)num2==0
            ex1: (x?3:0) to (x*3)
            ex2: (x?7:0) to (x*7)
        iii)
            (*A) or (*B) //one might be shorter

    b)num1<num2
        i)((num1+1)==num2)
            ex1: (x?4:5) to (5-x)
            ex2: (x?7:8) to (8-x)
        ii)num1==0
            ex1: (x?0:3) to (!x*3)
            ex2: (x?0:7) to (!x*7)
        iii)
            (*A) or (*B) //one might be shorter

    c)num1==num2
        i)
            ex1: (x?5:5) to (5)
            ex2: (x?-3:-3) to (-3)

    (*A) use ((x*(num1-num2))+num2)
        ex1: (x?8:4)   to ((x*4)+4)
        ex2: (x?4:8)   to ((x*-4)+8)

        ex3: (x?6:-4)  to ((x*10)-4)
        ex4: (x?-4:6)  to ((x*-10)+6)

        ex5: (x?4:-6)  to ((x*10)-6)
        ex6: (x?-6:4)  to ((x*-10)+4)

        ex7: (x?-5:-9) to ((x*4)-9)
        ex8: (x?-9:-5) to ((x*-4)-5)

    (*B) use ((!x*(num2-num1))+num1)
        ex1: (x?8:4)   to ((!x*-4)+8)
        ex2: (x?4:8)   to ((!x*4)+4)

        ex3: (x?6:-4)  to ((!x*-10)+6)
        ex4: (x?-4:6)  to ((!x*10)-4))

        ex5: (x?4:-6)  to ((!x*-10)+4)
        ex6: (x?-6:4)  to ((!x*10)-6)

        ex7: (x?-5:-9) to ((!x*-4)-5)
        ex8: (x?-9:-5) to ((!x*4)-9)

참고 : 이 외에도, 당신은 불필요한 제거해야합니다 0-, +0, +-

주 2 : 고립 된 경우가 있습니다 (x) !== (x?1:0)로는, x해야 typeof === "number"작동하는. 그러나이 경우에는 (-x)잘 작동합니다.

참고 3 : 저축을 찾을 수없는 경우 단순히 전자를 사용하십시오(x?y:z)

이전에는 메소드 B가 A를 이길 수 없다고 생각했지만 예외는 있습니다.

(x?97:100) //original

(-3*x+100)
(3*!x+97)

우리를 위해 단순화 시키는 github 프로젝트 를 만들었습니다 ( jsFiddle demo )


@ ajax333221 void 0(함수는 아니지만 키워드)은 값이 아니며 단순히를 반환합니다 undefined.
Camilo Martin

당신이 맞다 @CamiloMartin, 또한 지금은 그러나,이 답변에 포인트를 참조 a작동하는 1 또는 0 중 하나를해야합니다
ajax333221

@ ajax333221 예, 실제로 저에게 코드 골프에 관한 재미있는 점은 대부분의 최고의 트릭은 당신이하고있는 특정 일에 대해서만 작동한다는 것입니다. 방법, 당신은하지 않습니다 ... 댓글을 삭제
카밀로 마틴

9

tl; dr : ES6 기능을 사용하십시오!

화살표 기능

문서 : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
예 :

s = x => x*x
// s = function (x) {
//   return x * x;
// }

화살표 기능은 이미 15:4210 월 13 일 13 일에 언급되었습니다 . 그러나 그것은 for.. of멋지다. 보다 짧은 for each... in.
manatwork

2
배열 이해 구문이 잘못된 것 같습니다. 설명서 에 따르면 Python과 같아야합니다 b = [s(x) for (x of a)].
manatwork

@manatwork 위의 샘플들은 Traceur의 REPL에서 잘 작동합니다.
Florent

Traceur에 대해서는 전혀 모르지만 ECMAScript를 언급하고 Mozilla 설명서를 가리 켰습니다. 그리고 그것들 중 어느 것도 배열 이해력 이 당신이 쓴 것처럼 보이지 않습니다.
manatwork

1
배열 이해는 실제로 중간 쯤에 당겨졌습니다.
Isiah Meadows

9

학대 리터럴

최근 샘플 : "c"대문자인지 소문자 인지 , 문자가 아닌지 중요하지 않습니다.

"c"<{} // returns false, lower case
"C"<{} // returns true, upper case

3
어떻게 작동합니까?
암소 ck

2
@Cowsquack가 String({})제공합니다 "[object Object]".
Dennis

8

숫자가 부울로 바뀌는 방법을 사용하여 숫자를 비교하는 방법 :

무언가가 양수 인지 확인하려면 해당 양을 빼고 ifand else블록 내부의 내용을 되돌릴 수 있습니다 .

//simplified examples:
x==3?"y":"n"; <- 13 Chars
x-3?"n":"y"; <- 12 Chars

//expanded examples:
if(x==3){
    yes();
}else{
    no();
}

if(x-3){
    no();
}else{
    yes();
}

그리고 음수 (*와 다른 -1) 를 비교 하려면 빼기 대신이 숫자 를 추가 하면됩니다.

* 글쎄, 당신은 반드시 사용할 수 x.indexOf(y) + 1있지만 특별한 경우에는 대신 -1사용할 수 있습니다 ~x.indexOf(y).


8

Mozilla의 비표준 "표현식 폐쇄"기능을 사용하여 SpiderMonkey / Firefox 또는 Rhino 엔진에서만 작동하는 스크립트에 많은 문자를 저장하십시오. 예를 들어

function foo(){return bar}

된다

function foo()bar

더 많은 트릭에 대해서는 스택 오버플로 페이지 를 참조하십시오 .


2
Javascript가 아닙니다. 우주 정거장 !!!
토마스 에딩

1
ECMAScript 6을 구출하십시오! ->bar
Ry-

5
ECMAScript 6 : let foo = () => bar;위의 골프 코드보다 짧습니다.
Isiah Meadows

1
ECMAScript 6 : foo=_=>bar더 짧습니다.
ETHproductions

그 연결이 끊어졌습니다.
Cyoce



8

부울로 변환 :

if(b){b=true}else{b=false}
b=b?true:false;
b=b?!0:!1;
b=!!b;

참고 : 이 변경 0, "", false, null, undefinedNaNfalse(로 다른 모든 것들 true)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.