2017-01-07 5 views
1

52枚のカードのデッキを作成しようとしています。私はそれを二重forループで簡単に作成できますが、複雑さはO(n2)です。だから、私はmap()とforEach()配列メソッドを使って遊んでいましたが、物事を返す必要があるものは複雑です。以下は私のコードです。Forループ、マップ、forEach Javascript

(function deckCreate() { 
 
    var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 
 
    var suits = ["clubs", "diamonds", "hearts", "spades"]; 
 
    var newDeck = values.map(function(xValue) { 
 
    suits.forEach(function(xSuit) { 
 
     return [xSuit,xValue]; 
 
    }); 
 
    }); 
 
    return newDeck; 
 
}());

それは長さ13内のすべての未定義の配列を与えます。私はmap()の前にforEach()をスワップしようとしましたが、結果は同じでした。

これらの機能の中でconsole.log()が見つかった問題は、要素が互いにマップされていないが、すべて別々に印刷されていることでした。何が問題なのでしょうか?

+0

をスクリプトの実行のスピードを上げるためにあなたの目標ですか? – sinisake

+0

'.forEach'が何も返さないため、' undefined'となっています。それを '.map'に変更し、その行の先頭に' return'を置くと正しく動作します。私が驚いているのは、これまで1ミリ秒以上かかる場合でした。 – DonovanM

+1

@sinisake nahはネストされたfor-loopsではなく新しいやり方を学ぼうとしています – Jamie

答えて

0

map関数から何も返されていないので、暗黙の戻り値はundefined、したがって配列は13 undefinedです。

suits.forEachは、return suits.mapである必要があります。これは13個の要素の配列を与えます。各要素は4つの要素の配列です。内部の配列の各要素は2つの要素[suit, value]配列です。

var newDeck = values.map(function(xValue) { 
    return suits.map(function(xSuit) { 
    return [xSuit,xValue]; 
    }); 
}).reduce(function (a, b) { return a.concat(b) }); 
+0

'.reduce()'呼び出しの目的は何ですか? – guest271314

+0

@ guest271314私が言ったように、 'map(map(...))'の結果は '13(4(2))'要素のネストされた配列です。問題は、スーツ/ナンバーペアの52要素配列を生成する方法でした。 Reduceは、13 * 4配列を単一の52要素配列に連結します。最上位の配列を 'Array.prototype.concat.apply'に渡して、同じ結果を得ることもできます。 – meagar

+0

Questionのテキストは、「52桁のスーツ/数字のペア」という期待される結果を記述していますか? – guest271314

0

あなたが問題を抱えている理由は、あなたの外側.map()コールバックから戻っていないということです:あなたは、あなたがしている52の要素配列にトップレベルの配列が後に続いreduceすることができます。あなたがしたとしても、[].forEachはそのコールバック内で何が起こっても常にundefinedを返します。

したがって、forEachを使用して内部配列を反復するので、mapから13個の未定義配列を取得します。私は、あなたは明らかに自分自身を学び、改善しようとしている方法を見て

const first = [1, 2, 3]; 
 
const second = ['a', 'b', 'c']; 
 

 
const mapped = first.map(function(digit) { 
 
    return second.map(function(letter) { 
 
    return [digit, letter]; 
 
    }); 
 
    }); 
 

 
console.log(mapped);

あなたが使用してすべきこと.map()すべての方法ダウンしていると道のすべてのステップを返しますこの例をあなたの特定のケースに合わせて調整しておきます。

P.S.フラット化された配列が必要な場合は、[].reduce()[].concat()をご覧ください。

+0

_ "return [xSuit、xValue]' "_ Questionのパターンは「最初に」、 'second'は' .map() 'の呼び出しで逆になりますか? – guest271314

+0

@Madara Uchihaは答えのためにsenpaiに感謝します。私は今reduce()メソッドをチェックアウトします – Jamie

1

私はそれを簡素化する方が良いと思います。

それはスーツの名前でリストを取得するのに十分だように、我々は、ちょうど4スーツがあることを知っている:

function createDeck() { 
 
    var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 
 
    var deck = {"clubs": values.slice(), "diamonds": values.slice(), "hearts": values.slice(), "spades": values.slice()}; 
 
    return deck; 
 
} 
 

 
var deck = createDeck(); 
 

 
console.log('CLUBS:', deck.clubs); 
 
console.log('DIAMONDS:', deck.diamonds); 
 
console.log('HEARTS:', deck.hearts); 
 
console.log('SPADES:', deck.spades);

P.S.私の場合、生成、反復などを簡単に使用できるようにするクラスを作成します。

function Deck() { 
 
    var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 
 
    var suits = ['clubs', 'diamonds', 'spades', 'hearts']; 
 
    
 
    this.getSuits = function() {return suits.splice();} 
 
    this.getValues = function() {return values.splice();} 
 
    
 
    var asObject; 
 
    this.asObject = function() { 
 
    if(asObject) return asObject; 
 
    
 
    asObject = {}; 
 
    suits.map(function(suit) { 
 
     asObject[suit] = values.slice(); 
 
    }); 
 
    return asObject; 
 
    }; 
 
    
 
    var asArray; 
 
    this.asArray = function() { 
 
    if(asArray) return asArray; 
 
    asArray = []; 
 
    
 
    suits.map(function(suit) { 
 
     values.map(function(value) { 
 
     asArray.push([suit, value]); 
 
     }); 
 
    }); 
 
    return asArray; 
 
    } 
 
    
 
    this.iterate = function(fn) { 
 
    this.asArray().map(fn); 
 
    } 
 
} 
 

 
var deck = new Deck(); 
 

 
deck.iterate(function(card) { 
 
    console.log('CARD: ', card[0], card[1]);    
 
}); 
 

 
console.log(deck.asObject()); 
 
console.log(deck.asArray());

+0

'newDeck'はIIFEの外でどのようにアクセスされますか? – guest271314

+0

ああ、私は分かっています。 – num8er

+1

@ guest271314今すぐチェックしてください(; – num8er

1

シンプルforループを使用してください。右のスーツを取得し、各訴訟のためのカード番号を取得するremainder operator%を使用するようにsuits[Math.floor(i/13)]を使用します。私はただ聞いてもらえ

function deckCreate() { 
 
    var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; 
 
    var suits = ["clubs", "diamonds", "hearts", "spades"]; 
 
    var newDeck = []; 
 

 
    for (var i = 0; i < 52; i++) { 
 
    newDeck.push([suits[Math.floor(i/13)], values[i % 13]]); 
 
    } 
 

 
    return newDeck; 
 
} 
 

 
var result = deckCreate(); 
 

 
console.log(result);

+0

あなたは正しいですが、私がJ、Q、Kなどのような顔の値を最初に使用したい場合は助けになりません。 ):) – Jamie

+0

@Jamie - 元の 'values'配列で動作するように答えを変更しました。 –

関連する問題