2
votes

Trier le tableau d'objets à l'aide d'autres tableaux

Je crée ce tableau d'objets:

`
` [ { color: 'Blue', brightness: 'Soft' },
  { color: 'Blue', brightness: 'Medium' },
  { color: 'Blue', brightness: 'Principal' },
  { color: 'Magenta', brightness: 'Soft' },
  { color: 'Magenta', brightness: 'Medium' },
  { color: 'Magenta', brightness: 'Principal' } ]
`
` [ 'Principal', 'Soft', 'Medium' ]
[ { color: 'Blue', brightness: 'Medium' },
  { color: 'Magenta', brightness: 'Medium' },
  { color: 'Blue', brightness: 'Soft' },
  { color: 'Magenta', brightness: 'Soft' },
  { color: 'Blue', brightness: 'Principal' },
  { color: 'Magenta', brightness: 'Principal' } ]
`
` [ 'Blue', 'Magenta' ]
[ { color: 'Magenta', brightness: 'Medium' },
  { color: 'Magenta', brightness: 'Soft' },
  { color: 'Magenta', brightness: 'Principal' },
  { color: 'Blue', brightness: 'Medium' },
  { color: 'Blue', brightness: 'Soft' },
  { color: 'Blue', brightness: 'Principal' } ]

Je veux un nouveau tableau avec des objets dans cet ordre:

const palette1 = sortArrayByAnotherArray(
  palette,
  brightnessOrder,
  'brightness'
)
const palette2 = sortArrayByAnotherArray(
  palette1,
  colorOrder,
  'color'
)

console.log('\n', palette)

console.log('\n', brightnessOrder)
console.log(palette1)

console.log('\n', colorOrder)
console.log(palette2)

Donc c'est le résultat que j'aimerais avoir:

function sortArrayByAnotherArray(array: any[], order: number[] | string[], key: string) {
  const newArray = array.slice(0).sort((a, b) => {
    const A = a[key]
    const B = b[key]
    return order.indexOf(A) < order.indexOf(B) ? 1 : -1
  })
  return newArray
}

J'essaye cette fonction:

const colors = [
  {
    color: 'Blue',
    brightness: 'Principal',
  },
  {
    color: 'Blue',
    brightness: 'Soft',
  },
  {
    color: 'Blue',
    brightness: 'Medium',
  },
  {
    color: 'Magenta',
    brightness: 'Principal',
  }
  {
    color: 'Magenta',
    brightness: 'Soft',
  },
  {
    color: 'Magenta',
    brightness: 'Medium',
  },
]

Je l'appelle de cette façon:

const colorOrder = ['Blue', 'Magenta']
const brightnessOrder = ['Principal', 'Soft', 'Medium']

Le résultat est:

const palette = [
  {
    color: 'Blue',
    brightness: 'Soft',
  },
  {
    color: 'Blue',
    brightness: 'Medium',
  },
  {
    color: 'Blue',
    brightness: 'Principal',
  },
  {
    color: 'Magenta',
    brightness: 'Soft',
  },
  {
    color: 'Magenta',
    brightness: 'Medium',
  },
  {
    color: 'Magenta',
    brightness: 'Principal',
  }
]

C'est un désordre, l'ordre n'est pas comme celui des tableaux: couleurs sont inversées ainsi que les valeurs de luminosité. Ensuite, je pense qu'appeler cette fonction deux fois (ou plus) crée des problèmes. Y a-t-il un moyen de résoudre ce problème? Existe-t-il une manière intelligente de faire ce dont j'ai besoin?


1 commentaires

qu'en est-il des valeurs inconnues dans les tableaux d'ordre? avez-vous une liste complète, ou des éléments inconnus devraient-ils être déplacés vers le haut ou le bas ou à tout autre endroit?


3 Réponses :


0
votes

Si le résultat est inversé, vous pouvez essayer d'inverser la condition de tri

return order.indexOf(A) > order.indexOf(B) ? 1 : -1


0 commentaires

1
votes

Vous pouvez enchaîner la commande souhaitée avec OR logique || et les deltas des index.

.as-console-wrapper { max-height: 100% !important; top: 0; }
function sortArrayByAnotherArrays(data, orders) {
    const
        getObject = array => array.reduce((r, k, i) => (r[k] = i + 1, r), {}),
        objects = orders.map(([k, a]) => [k, getObject(a)]);

    return data
        .slice()
        .sort((a, b) => {
            var v;
            objects.some(([k, o]) => v = o[a[k]] - o[b[k]]);
            return v;
        });
}

const
    palette = [{ color: 'Blue', brightness: 'Soft' }, { color: 'Blue', brightness: 'Medium' }, { color: 'Blue', brightness: 'Principal' }, { color: 'Magenta', brightness: 'Soft' }, { color: 'Magenta', brightness: 'Medium' }, { color: 'Magenta', brightness: 'Principal' }],
    colorOrder = ['Blue', 'Magenta'],
    brightnessOrder = ['Principal', 'Soft', 'Medium'],
    ordered = sortArrayByAnotherArrays(
        palette,
        [
            ['color', colorOrder],           // [key, values in order]
            ['brightness', brightnessOrder]
        ]
    );

console.log(ordered);

Une approche pour trier une copie avec une fonction et des tableaux d'ordre donnés.

.as-console-wrapper { max-height: 100% !important; top: 0; }
const
    palette = [{ color: 'Blue', brightness: 'Soft' }, { color: 'Blue', brightness: 'Medium' }, { color: 'Blue', brightness: 'Principal' }, { color: 'Magenta', brightness: 'Soft' }, { color: 'Magenta', brightness: 'Medium' }, { color: 'Magenta', brightness: 'Principal' }],
    colorOrder = ['Blue', 'Magenta'],
    brightnessOrder = ['Principal', 'Soft', 'Medium'];

palette.sort((a, b) => 
    colorOrder.indexOf(a.color) - colorOrder.indexOf(b.color) ||
    brightnessOrder.indexOf(a.brightness) - brightnessOrder.indexOf(b.brightness)
);

console.log(palette);


3 commentaires

Merci! J'essaie de généraliser ce processus en créant cette fonction: function sortBy (datasetToSort: any [], orders: {order: string [] | number [], key: string} []) {const datasetToSortCloned = datasetToSort.slice ( 0) const result = datasetToSortCloned.sort ((a, b) => {const quelque chose = orders.map ((o, i) => {const {order, key} = o return order.indexOf (a ['key' ]) - order.indexOf (b ['key'])}) // quelque chose [0] || quelque chose [1] || ...}) retourne le résultat} Mais comment puis-je faire quelque chose [0] || quelque chose [1] || ... ?


Merci mais cela ne semble pas fonctionner. Regardez ici: codesandbox.io/s/admiring-rgb-4y2tn


le nom de clé du tri doit correspondre au nom donné dans l'objet. au lieu de color , vous avez besoin de colorName , sinon la propriété ne peut pas être adressée correctement.



0
votes

Triez selon la différence d'index de la couleur de chaque objet dans le colorOrder , et alternez avec la différence d'index de la luminosité de chaque objet dans le brightOrder .

Gardez à l'esprit que .sort tri sur place - trié est le même objet que palette . Si vous ne voulez pas muter le tableau d'origine, clonez-le d'abord.

const palette=[{color:"Blue",brightness:"Soft"},{color:"Blue",brightness:"Medium"},{color:"Blue",brightness:"Principal"},{color:"Magenta",brightness:"Soft"},{color:"Magenta",brightness:"Medium"},{color:"Magenta",brightness:"Principal"}];

const colorOrder = ['Blue', 'Magenta'];
const brightnessOrder = ['Principal', 'Soft', 'Medium'];

const sorted = palette.sort((a, b) => (
  colorOrder.indexOf(a.color) - colorOrder.indexOf(b.color) ||
  brightnessOrder.indexOf(a.brightness) - brightnessOrder.indexOf(a.brightness)
));
console.log(sorted);


0 commentaires