2016-12-20 3 views
1

Dans mon application de poker que j'ai un tableau des mains, chaque tableau étant à la main des objets de carte sélectionnés au hasard avec valeur et costume:Array.reduce sur un tableau multidimensionnel de tableau d'objets

[ [ { value: 5, suit: 's' }, 
    { value: 4, suit: 's' }, 
    { value: 6, suit: 'c' }, 
    { value: 11, suit: 'd' }, 
    { value: 12, suit: 'c' } ], 
    [ { value: 9, suit: 'd' }, 
    { value: 12, suit: 'h' }, 
    { value: 8, suit: 'c' }, 
    { value: 12, suit: 's' }, 
    { value: 2, suit: 's' } ], 
    [ { value: 4, suit: 'h' }, 
    { value: 6, suit: 's' }, 
    { value: 10, suit: 'c' }, 
    { value: 3, suit: 'd' }, 
    { value: 7, suit: 'd' } ] ] 

Pour préparer les mains pour l'évaluation je veux utiliser Array.reduce pour retourner un tableau d'objets de la main. Ainsi, la sortie serait:

[ 
    { 
    values: [5, 4, 6, 11, 12], 
    suits: ['s', 's', 'c', 'd', 'c'] 
    },  
    { 
    values: [9, 12, 8, 12, 2], 
    suits: ['d', 'h', 'c', 's', 's'] 
    }, 
    { 
    values: [4, 6, 10, 3, 7], 
    suits: ['h', 's', 'c', 'd', 'd'] 
    } 
] 

J'ai essayé cela avec la mise en œuvre de emboîtées de forEach, mais son échec et je ne sais pas pourquoi. J'ai deux console.log dans quelle sortie comme prévu, mais à la fin des mains est identique à l'entrée.

let temp = [] 
hands.forEach((el) => { 
    temp = el 
    el = {} 
    el.values = [] 
    el.suits = [] 
    console.log(el) //expected output 
    temp.forEach((obj) => { 
    el.values.push(obj.value) 
    el.suits.push(obj.suit) 
    console.log(el) //expected output 
    }) 
}) 
console.log(hands) //same as original 
+3

* "Je veux utiliser réduire" * ... alors où votre code tente-t-il de le faire? Ce n'est pas un service d'écriture de code. Ce site fonctionne en postant ** votre code ** qui ne fonctionne pas comme prévu et les gens vous aident à corriger cela – charlietfl

+1

J'ai fait des tentatives de code, je ne pensais pas qu'ils seraient utiles à publier car il semblait que toute réponse valide serait une réécriture complète de ma mise en œuvre. La critique juste cependant, je le garderai dans l'esprit. –

+0

Mais vous manquez également le point que vous apprenez de vos erreurs. * Donner un poisson à un homme, ou enseigner à un homme à pêcher * – charlietfl

Répondre

2

Vous devez penser à la forme de vos données d'entrée (DATA) et de sortie (DATA')

enter image description here

Remarque 1: 1 relation entre HAND et HAND' qui signifie que nous utiliserons Array.prototype.map pour une transformation. D'autre part, CARD a un N: 1 relation avec HAND' meaing nous allons utiliser Array.prototype.reduce pour cette transformation

enter image description here

Donc, gardez à l'esprit alors que nous travaillons, nous allons faire une carte et réduire

const data = 
 
    [ [ { value: 5, suit: 's' }, 
 
     { value: 4, suit: 's' }, 
 
     { value: 6, suit: 'c' }, 
 
     { value: 11, suit: 'd' }, 
 
     { value: 12, suit: 'c' } ], 
 
    [ { value: 9, suit: 'd' }, 
 
     { value: 12, suit: 'h' }, 
 
     { value: 8, suit: 'c' }, 
 
     { value: 12, suit: 's' }, 
 
     { value: 2, suit: 's' } ], 
 
    [ { value: 4, suit: 'h' }, 
 
     { value: 6, suit: 's' }, 
 
     { value: 10, suit: 'c' }, 
 
     { value: 3, suit: 'd' }, 
 
     { value: 7, suit: 'd' } ] ] 
 

 
let output = 
 
    data.map(cards => 
 
    cards.reduce(({values, suits}, {value, suit}) => ({ 
 
     values: [...values, value], 
 
     suits: [...suits, suit] 
 
    }), {values: [], suits: []})) 
 

 
console.log(output)

Maintenant, bien sûr, cela semble un peu dense, donc ce serait bien si nous pouvions un peu réduire la complexité.En faisant quelques adaptateurs pour cari map et reduce nous pouvons exprimer une fonction qui effectue votre transformation assez bien

const data = 
 
    [ [ { value: 5, suit: 's' }, 
 
     { value: 4, suit: 's' }, 
 
     { value: 6, suit: 'c' }, 
 
     { value: 11, suit: 'd' }, 
 
     { value: 12, suit: 'c' } ], 
 
    [ { value: 9, suit: 'd' }, 
 
     { value: 12, suit: 'h' }, 
 
     { value: 8, suit: 'c' }, 
 
     { value: 12, suit: 's' }, 
 
     { value: 2, suit: 's' } ], 
 
    [ { value: 4, suit: 'h' }, 
 
     { value: 6, suit: 's' }, 
 
     { value: 10, suit: 'c' }, 
 
     { value: 3, suit: 'd' }, 
 
     { value: 7, suit: 'd' } ] ] 
 

 

 
const map = f => xs => xs.map(f) 
 

 
const reduce = f => y => xs => xs.reduce(f, y) 
 

 
const handAppendCard = ({values, suits}, {value, suit}) => ({ 
 
    values: [...values, value], 
 
    suits: [...suits, suit] 
 
}) 
 

 
const makeHands = 
 
    map (reduce (handAppendCard) ({values:[], suits:[]})) 
 

 
let output = makeHands (data) 
 

 
console.log(output)

C'est juste une façon d'aborder le problème. J'espère que vous avez pu en apprendre quelque chose^_^

+1

J'ai appris une tonne de cette réponse incroyable. Je vous remercie!!! * arcs * Je ne suis pas digne :) –

+1

Aww shucks. Vraiment, je suis heureux de pouvoir aider. Faites-moi savoir si vous avez d'autres questions^_ ^ – naomik

1

Là vous allez - une solution en utilisant Array.prototype.reduce imbriquées fonctions:

var array=[[{value:5,suit:'s'},{value:4,suit:'s'},{value:6,suit:'c'},{value:11,suit:'d'},{value:12,suit:'c'}],[{value:9,suit:'d'},{value:12,suit:'h'},{value:8,suit:'c'},{value:12,suit:'s'},{value:2,suit:'s'}],[{value:4,suit:'h'},{value:6,suit:'s'},{value:10,suit:'c'},{value:3,suit:'d'},{value:7,suit:'d'}]]; 
 

 
var result = array.reduce(function(p, c) { 
 
     p.push(c.reduce(function(a, b) { 
 
     a.values.push(b.value); 
 
     a.suits.push(b.suit); 
 
     return a; 
 
     }, {values: [],suits: []})); 
 
    return p; 
 
    },[]); 
 

 
console.log(result);
.as-console-wrapper {top: 0;max-height: 100%!important;}

-1

Voici une solution simple avec string concat et reduce. Vous pouvez essayer quelque chose comme:

var reduced = []; 
//here a is your initial array 
for(var i=0; i<a.length;i++){ 
    reduced.push(a[i].reduce(function(prev,curr){ 
     var obj={value:prev.value+','+curr.value,suit:prev.suit+','+curr.suit};return obj})); 
} 
console.log(reduced) 

EDIT: Comme par @Barmar commentaire cette chaîne retourne. Si vous voulez un tableau que vous pouvez faire:

for(var i=0; i<a.length;i++){ 
    var tempElm =a[i].reduce(function(prev,curr) { 
     var obj= {value:prev.value+','+curr.value,suit:prev.suit+','+curr.suit};return obj}); 
     tempElm['value'] = tempElm['value'].split(); 
     tempElm['suit']= tempElm['suit'].split(); 
     reduced.push(tempElm); 
} 
console.log(reduced) 

EDIT 2: Avec la critique juste pour le correctif ci-dessus (ce qui ajoute une sur la tête de conversion chaîne à tableau) Vous pouvez directement créer un tableau plutôt comme suit:

var reduced = []; 
for(var i=0; i<a.length;i++){ 
    var valArray = []; var suitArray=[]; 
    var tempElm = a[i].reduce(function(prev,curr) { 
     valArray.push(curr.value);suitArray.push(curr.suit); 
     var obj= {value:valArray,suit:suitArray}; 
     return obj; 
    },null); 
console.log(reduced) 
+2

Il veut des tableaux dans son résultat, pas des chaînes concaténées. – Barmar

+0

@Barmar merci pour le commentaire ... édité le message pour refléter les changements –

+1

C'est une solution idiote. Pourquoi faire une chaîne et ensuite diviser en un tableau quand vous pouvez simplement créer un tableau en premier lieu? – Barmar