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()ドット表記で2回呼び出す代わりに、名前を保存し、ブラケット表記で関数を呼び出す方が短くなります。

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

-対-

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

7
単項プラス演算子を使用して、文字列を数値に強制する方が安価です。aおよびbが文字列の場合、+a+b数値に変換して追加することができます。
ピーターオルソン

8
私は私が使用するつもりだ誓うd- -bいつか私のコードに...
ジョン・ドヴォルザーク

4
+ a + bは機能しません(少なくとも私の場合は...)// a = "1"、b = "1"、+ a + b // "11"を与える
imma 14年

2
あなたはより多くの2倍の機能を使用している場合は、「リピート機能のために使用アレイアクセス呼び出し」は同じオブジェクトに、どのようなちょっと短いのは、のような新しいメンバーに機能を割り当てることですa.f=a.longfunctionname;a.f(b);a.f(c);a.f(d)
マーティン・エンダー

131

引用符を保存するために数字で分割する:

"alpha,bravo,charlie".split(",") // before
"alpha0bravo0charlie".split(0)   // after

2
それは動作し、私はそれを複数の数字に使用しました。
イサイアメドウズ

12
笑これは実際には非常に創造的である
ニック・ニューマン

9
ES6で、これはもはや問題ではありません、あなただけ行うことができます.split`...`
デヴィッド・アーチボルド

"alpha,bravo,charlie".split`,`
カミルキールチェフスキ

56

中括弧を避けるためにコンマ演算子を使用します(Cに適用されます)。

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

の代わりに

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

これは1文字長くなります。


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))

これは、a Dateがエポックからミリ秒単位でJavaScriptに内部的に格納されているために機能し、整数演算を実行しようとするとnew Date強制的に変換され123somebignumber456ます。

もちろん、これらの「ランダムな」数値は、特に連続して複数回呼び出す場合は特にランダムではないので、注意してください。


1
読みながら、ちょうどこの答えを覚えてもっと虚偽のプログラマが時間について信じている「21。2つの日付オブジェクトを隣り合わせに作成すると、それらは同じ時刻を表します。(素晴らしいハイゼンバグジェネレーター)」
セバスチャンサイモン

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回以下しか使用しない場合はさらに良いでしょう。一方、矢印関数は、ほぼ同じ目的を果たすため、文字の削減にはるかに優れており、クラスはゴルフコードではほとんど役立ちません。
イサイアメドウズ

サポートが重要な場合、fxでは矢印関数はサポートされません。ie11
ジムウォルフ

35

これはあまり知られておらず、あまり使用されていませんが、適切な状況で使用すると印象的です。引数を取らず、呼び出されたときに常に異なる数値を返す関数を考えてください。返された数値は計算に使用されます。

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

通常、1文字の変数名を使用してこの関数を短縮できます。

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バイトが保存されます。
イサイアメドウズ

を置き換えr()たり、短くしたりすることはできますか?
ニック・ニューマン

3
r={valueOf:Math.random}それはただの天才だ:D
ETHproductions

1
@Isiahは、ええよく、あなたはそれを行うことができ、今 :-D
アンディ・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;

配列を使用して繰り返し文字列を作成する

特定の文字の長い文字列を初期化する場合、長さn + 1の配列を作成することで初期化できます。ここで、nは文字を繰り返したい回数です。

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

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

文字列が大きいほど、節約量は大きくなります。

数字の解析

単なる数値である文字列型を数値型に結合する代わりに、または結合するときに+and ~演算子を使用します。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
配列を使用して繰り返し文字列を作成するための+1-そのことを考えていませんでした。
mellamokb

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
これは、引数を受け入れない関数にも適用できます。
ケーシーチュウ

3
関数が引数を受け取る場合でも[1,2,3].join('',i=5)、中括弧のペアを保存する場合のように、関数は便利です。
DocMax

3
@DocMax:そのためにカンマ演算子を使用できます- i=5,[1,2,3].join()
コンラッドボロウスキ

@GlitchMr:できましたが、キャラクターを保存しません。たいていの場合、よりクリーンになることに同意します。現時点では文字を保存できないかもしれませんが、現時点では文字を保存できない場合があると思います(そして間違いかもしれません)。
DocMax

@DocMax ASIを利用している場合のみ。
イサイアメドウズ

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)

(私はaを編集しました)ちょっとしたタイプミスですが、とても賢いです!これは、同じ長さのネストされたループでのみ機能することに注意してください(私が間違っていない限り)。
カミロマーティン

1
@CamiloMartinいいえ、ループの長さは同じである必要はありません。結果の反復回数はでi*jあり、除算/モジュラス演算子はiおよびの個々の値を取得しますj
quietmint

@ user113215その通り、素晴らしい!:)例を編集して回答を編集しました。
カミロマーティン

23

Unicodeショートカット

大きなゴルフチャレンジでビルトインプロパティの地獄を使用する場合は、すべてのプロパティを1文字相当にエイリアスできます。

[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 Chromeを使用していますが、これらはすべて未定義です。
SuperJedi224

その場合、Firefox固有のものでなければなりません。ご不便おかけしてすみません。
ベベ

なぜこれらすべてが特殊文字なのですか?印刷可能なASCIIを使用しないのはなぜですか?(入力しやすく、信頼性が高く、ゴルフ用に1バイトのみ)
チョイス

これには属性Mathがないため、実際には機能しません.prototypeMathただし、を削除すると、これらをすべて1バイト文字に割り当てる114バイトのスニペットになりました。ここで見つけることができます。
ETHproductions 16

1
することもできますゴルフレンジにすべてのこれらのプロパティを移動を犠牲にして106バイトに私の解決策À- ÿ、まだ(JSがサポートしている)ISO-8859-1エンコーディングで1バイトごとです。Firefox 50では、残念ながらこの.localeCompareメソッドはon ×になりますが、通常は問題になりません。ソース
ETHproductions 16

22

多くの場合whileforループをループに変換することは同等です。

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

ただし、2番目の形式では、変数の初期化を組み合わせることができます。

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

2番目の形式は、最初の形式より1文字短いことに注意してください。


6
または、さらに良いことに、forループを使用します。私が経験した限りでは、forループを使用してコードが大きくなる場合は実際にありません。
イサイアメドウズ

22

例外濫用

文字列/文字リテラルが禁止されている場合、try catchブロックを使用できます。

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

str等しい"something"

さらに文字列が必要な場合は、数字(たとえばゼロ)でチェーンできます

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++<=nである1(それが偽になった場合、ループはなくなりかかわら実行を停止しますので)その真の、あなただけの変数に直接条件を割り当てることができたときに:

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を返します。
トマスランカース

15

配列の合計/積/商

ES5:17バイト

eval(a.join('+'))

ES6:15バイト

eval(a.join`+`)

もちろん、製品や商など+、好きなものに交換できます。*/


14

ビット単位の演算を使用して、数値をゼロに丸めます:

// 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がビット単位の約2倍の速度になります。
mellamokb

とても奇妙です。私にとっては、Chromeではほぼ同じ速度と超高速の両方ですが、FFではビット単位はChromeよりもはるかに高速であり、Math.floor非常に遅いです。ほとんど使用しないでください
vsync

コメントを最新の状態に保つために、現在のFxでは高速かつほぼ同等です。ではない...それは、周囲のコードに比べて、最初の場所でのボトルネックになりそうだということ
ホタル

14

ループのヒントI

最後に使用した時間を1変更することで、ループ時にキャラクターを保存できますi

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

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

注:でも動作し--ます(ただし、無限ループを回避するためにループを適宜変更します)


ループのヒントII

インクリメント演算子と値で遊んで1つのキャラクターを保存できる特定のシナリオがあります。

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関数の呼び出しを短い式に置き換えます

//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

注目に値するのは、いくつかのインスタンスでゼロの代わりに文字列を使用して、ループのあちこちで数バイトを保存できることです。

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

1
私は以前にコンソールで "" ++を試してみましたが、それが機能するかどうか疑問に思っていました。もちろん最初に変数に入れなければなりません。ありがとう!
バルタン

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か?
ママファンロール

おっと、はい。それを指摘してくれてありがとう。(何らかの理由で、@(ユーザー名)を実行できません...)
ETHproductions

おそらく、ユーザー名の文字が逆さまになっているからでしょう:)
ママファンロール

1
上限については、x%1?-~x:x(9文字)がより適切な代替手段です。ただし、フローリングの選択肢0|xおよびのように、~~x正の数に対してのみ機能します。
トマスランカース

9

三項演算子を使用して2つの数値のいずれかを選択し、条件がブールまたは数値の 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デモ


@ ajax333221 void 0(関数ではなく、キーワード)は値ではなく、単にを返しますundefined
カミロマーティン

あなたが正しいです@CamiloMartin、また、私は今しかし、この答えのポイントを参照してくださいaそれを動作させるための1または0のいずれかでなければなりません
ajax333221

@ ajax333221はい、実際、コードゴルフの面白い点は、ほとんどの最高のトリックはあなたがしている特定の事柄に対してのみ機能するということです。方法、あなたはしていない持っている ...コメントを削除する
カミロ・マーティン

9

tl; dr: ES6機能を使用してください!

矢印関数

Doc:https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/arrow_functions
例:

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

矢印関数は、1310月13日15:42にすでに言及されています。しかし、それはfor... ofクールです。さらに短いですfor each... in
マナトワーク14年

2
配列内包構文は間違っているようです。ドキュメントによると、Pythonのようになりますb = [s(x) for (x of a)]
マナトワーク14年

@manatwork上記のサンプルはTraceurのREPL
Florent 14年

Traceurについてはわかりませんが、あなたはECMAScriptについて言及し、Mozillaのドキュメントを指摘しました。そして、それらの配列内包表記は、あなたが書いたようには見えません。
マナトワーク14年

1
アレイの理解は実際には途中で引き出されました。
イサイアメドウズ14

9

虐待リテラル

最近のサンプル:"c"大文字であるか小文字であるかを確認し、文字でなくても問題ありません

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

3
これはどのように作動しますか?
牛は

2
@Cowsquack String({})はを与え"[object Object]"ます。
デニス

8

数値をブール値に変換する方法の助けを借りて、数値を比較する方法:

何かが正の数に等しいかどうかを確認する場合は、その量を減算しifelseブロック内およびブロック内にあったものを逆にすることができます。

//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

このようなトリックの詳細については、Stack Overflowページをご覧ください


2
それはJavascriptではありません。それは宇宙ステーションです!!!
トーマスエディング

1
ECMAScript 6が助けになります!->bar
Ry-

5
ECMAScriptの6:let foo = () => bar;上記golfedコードよりも皮肉短いです。
イサイアメドウズ

1
ECMAScript 6: foo=_=>barさらに短い。
ETHproductions

そのリンクは壊れています。
チョイス



8

ブール値への変換

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

注:これは変化し0""falsenullundefinedNaNするfalse(と他のすべてtrue

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.