javascript - Amestecă obiectul de obiecte sau afișează aleator elementele în Angular 2 în șablon


Am un obiect de obiecte cu o structură ca aceasta:

Și afișez toate imaginile în șablonul meu cu ajutorul Object.keys

în componentă am:

this.objectKeys = Object.keys;

în șablon:

<ul id="thumbnailsList">
  <li *ngFor="let key of objectKeys(newTmp)">
    <img src="{{newTmp[key].url}}">
  </li>
</ul>

Deocamdată totul funcționează bine, dar aș dori să amestec imaginile mele, astfel încât de fiecare dată când pagina va fi reîncărcată, imaginile să își schimbe ordinea.

Știu că obiectele nu au o ordine definită, așa că nu este posibil să manipulezi datele în componentă. Nu vreau să fac un array din ele, pentru că ideea unui obiect este căutarea rapidă printre obiecte (în viitor voi avea mii și mii de imagini și parcurgerea unui array nu este o soluție bună în acest caz, așa că aș vrea să păstrez obiectul în locul unui array)

Întrebarea mea este: care ar putea fi soluția posibilă aici? Există vreo posibilitate de a reordona imaginile direct în șablon fără a atinge componenta? Sau poate există vreo modalitate de a amesteca obiectele?

Răspuns #1

Poți crea un pipe și să-l incluzi în array-ul declarations al AppModule.

src/app/core/pipes/random-order.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'randomOrder' })
export class RandomOrderPipe implements PipeTransform {
  transform(list: Array<any>): Array<any> {
    const newList = [...list];
    newList.sort(() => Math.random() - 0.5);
    return newList;
  }
}
src/app/app.module.ts
import { RandomOrderPipe } from './core/pipes/random-order.pipe';

@Module({
  declarations: [RandomOrderPipe, ...],
  ...
})
src/app/app.component.html
<div>
  <div *ngFor="item in list | randomOrder">
    <!-- -->
  </div>
</div>

Răspunsul #2

Pentru a crea o funcție de amestecare, trebuie să lucrezi cu tablouri. Ceea ce poți face este, așa cum ai făcut, să obții cheile, dar ar fi mai ușor și mai intuitiv să folosești direct un tablou.

Până la urmă, reprezintă o listă de imagini, deci nu ar trebui să fie un obiect.

Funcția de amestecare poate fi codificată cu ajutorul reduce și splice:

const images = ['dog', 'cat', 'degu', 'mouse', 'snake'];

function shuffle(list) {
  return list.reduce((p, n) => {
    const size = p.length;
    const index = Math.trunc(Math.random() * (size - 1));
    p.splice(index, 0, n);
    return p;
  }, []);
};

console.log(shuffle(images));
console.log(shuffle(images));
console.log(shuffle(images));