1
votes

Comparer un tableau d'objets: façon Ramda

Il y a 2 tableaux d'objets, le premier est

const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 3 } },
]

et le second est

const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
]

Je veux prendre blocs tableau, prenez chaque objet de celui-ci et trouvez si le tableau conteneurs a un bloc avec un tel identifiant. Donc, si au moins un identifiant n'est pas trouvé, je veux interrompre la boucle et retourner false, sinon si tous les identifiants trouvés retournent vrai.

J'ai essayé de l'implémenter avec .some () code> mais je n'ai pas pu interrompre la boucle lorsque l'identifiant n'est pas trouvé.

J'apprécierais que vous conseilliez à Ramda un moyen de mettre en œuvre ceci.

Merci.


4 commentaires

alors vous ne devriez pas utiliser certains , peut-être qu'il y a un tous ?


Voulez-vous que tous les objets soient identiques ou au moins l'un d'entre eux?


@MaheerAli Je veux que tous les objets du tableau blocs aient des blocs similaires dans le tableau conteneurs


@appleapple Il existe une fonction .every () et j'ai déjà implémenté cette jsfiddle.net / qdagc5yv mais je ne sais pas si c'est une bonne solution, je veux aussi Ramda manière :)


5 Réponses :


0
votes

De manière non ramda, vous pouvez comparer chaque objet avec les autres éléments et utiliser une vérification approfondie.

const
    deep = id => o =>
        o && typeof o === 'object' && (o.id === id || Object.values(o).some(deep(id))),
    compare = (source, target) => source.every(({ id }) => target.some(deep(id))),
    blocks = [ { id: 1 }, { id: 2 }, { id: 3 }],
    containers = [{ block: { id: 1 } }, { block: { id: 2 } }, { block: { id: 3 } }]

console.log(compare(blocks, containers));


0 commentaires

0
votes

Vous pouvez utiliser la méthode equals () .

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
]

const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 3 } },
]

console.log(R.equals(containers.map(x => x.block.id),blocks.map(x => x.id)))


2 commentaires

Merci. Je ne veux pas comparer l'égalité des objets, je veux juste comparer le paramètre id .


@CroaToa Vous pouvez donc convertir les deux en tableau d'identifiants. puis comparez. Voir la modification.



1
votes

Vous pouvez le faire en utilisant R.differenceWith:

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
];

const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 4 } },
];

const diff = R.differenceWith((x,y) => x.id === y.block.id);
const mismatch = diff(blocks, containers).length > 0;

console.log(mismatch);


0 commentaires

0
votes

Il n'y a pas de Ramda Way TM particulier. Ramda est une bibliothèque, une boîte à outils ou, dans la description de Underscore, une ceinture à outils. Il est conçu pour rendre un certain style de codage plus facile à lire et à écrire dans JS. Mais cela ne veut pas du tout dicter la façon dont vous écrivez votre code.

Le principal objectif de Ramda est de faciliter la création d'applications grâce à des fonctions de composition, garantissant des avantages FP tels que l'immuabilité et la transparence référentielle.

Donc, pour ce problème, je pourrais commencer par quelque chose comme ceci:

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script><script>
const {compose, all} = R      </script>

Cette dernière fonction peut être rapidement réécrite en utilisant Ramda en

const hasBlock = (containers) => {
  const ids = containers .map (c => c.block.id)
  return (block) => ids .includes (block.id)
}

const allContained = compose (all, hasBlock)

const containers = [{block: {id: 1}}, {block: {id: 2}}, {block: {id: 4}}]

console .log (
  allContained (containers) ([{id: 1}, {id: 2}, {id: 3}]), //=> false
  allContained (containers) ([{id: 1}, {id: 2}, {id: 4}]), //=> true
  allContained (containers) ([{id: 4}, {id: 1}]),          //=> true
  allContained (containers) ([{id: 42}]),                  //=> false
)


0 commentaires

0
votes

Vous pouvez y parvenir avec JS / Lodash / Ramda presque exactement de la même manière.

JS / Lodash ayant les mêmes méthodes exactes pour chaque et certains et dans Ramda avec all et any:

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const blocks = [{ id: 1 },{ id: 2 },{ id: 3 }]
const containers = [{ block: { id: 1 } },{ block: { id: 2 } },{ block: { id: 3 } }]

const blocks2 = [{ id: 1 },{ id: 2 },{ id: 3 }]
const containers2 = [{ block: { id: 4 } },{ block: { id: 2 } },{ block: { id: 3 } }]

let hasAllBlocks = (blks, conts) => 
   blks.every(b => conts.some(c => c.block.id === b.id))

let hasAllBlocksLD = (blks, conts) => 
  _.every(blks, b => _.some(conts, c => c.block.id === b.id))

let hasAllBlocksR = (blks, conts) => 
   R.all(b => R.any(c => c.block.id === b.id, conts), blks)

console.log(hasAllBlocks(blocks, containers))   // true
console.log(hasAllBlocks(blocks2, containers2)) // false

console.log(hasAllBlocksLD(blocks, containers))   // true
console.log(hasAllBlocksLD(blocks2, containers2)) // false

console.log(hasAllBlocksR(blocks, containers))   // true
console.log(hasAllBlocksR(blocks2, containers2)) // false


0 commentaires