我正试图做一个六面体。因此,我从firestore中检索了一个十六进制集合,按ID对其进行了排序,将其移至10行(因此前10个进入“ row0”,接下来的10个进入“ row1”,依此类推),并使用ngFor显示它们
问题是当我显示它们时,我得到了:
row0
第1行
第10行
row11
第2行
第3行
第4行
第5行
第6行
第7行
第8行
第9行
所以我显然缺少了一些东西。我认为它们是乱序的,但是我正在console.logging行并按预期顺序看到它们:
行[row0:Array(10),row1:Array(10),row2:Array(10),row3:Array(10),row4:Array(10),...]对象
我可以看到该顺序似乎基于“行”之后的第一个数字,但不确定为什么。任何指针将不胜感激!
TS:
服务
export class FirestoreService {
constructor(private db:AngularFirestore) { }
getHexes(){
let hexRows = []
let hexes = this.db.collection('hexes', ref=> ref.orderBy('id')).valueChanges().subscribe(data => {
data.forEach((hex, index) => {
let rowNum = Math.floor(index / 10)
if(hexRows[`row${rowNum}`] == undefined){
hexRows[`row${rowNum}`] = []
}
hexRows[`row${rowNum}`].push(hex)
})
console.log('Rows', hexRows, typeof hexRows);
})
return hexRows
}
组件
ngOnInit() {
this.hexRows = this.afs.getHexes()
}
HTML:
组件
<div *ngFor="let row of hexRows | keyvalue">
{{row.key}}
</div>
更新
因此,在Deborah的领导下,我尝试使用comparefn并意外地“修复了它”。我做了一个名为'orderByRowNum'的快速测试函数,当我检查它是否运行时,看起来像按预期顺序排列了列表:
TS:
orderByRowNum = (a,b) => {
console.log('A', a);
return a
}
HTML:
<div *ngFor="let row of hexRows | keyvalue:orderByRowNum">
{{row.key}}
</div>
这可能是一个可怕的实现,我不确定100%为什么会起作用,但我要发布它,因为至少看起来像是进步。
答案 0 :(得分:0)
表面上看来localeCompare会有所帮助,但对我而言却无济于事,所以我不会仅仅依靠它。
您需要应用自然排序算法对键进行排序。
尝试一下。我从这里https://snipplr.com/view/36012/javascript-natural-sort/提取了javascript中的自然排序算法,并对其进行了重构以更好地适应打字稿规则。此外,还会应用localeCompare代替本地字符串压缩器。
private orderByRowNum = (aKv: KeyValue<string, any>, bKv: KeyValue<string, any>) => {
const rx: RegExp = /(\d+)|(\D+)/g;
const rd: RegExp = /\d+/;
const as: string = aKv.key;
const bs: string = bKv.key;
const a: RegExpMatchArray = String(as).match(rx);
const b: RegExpMatchArray = String(bs).match(rx);
while (a.length && b.length) {
const a1: string = a.shift();
const b1: string = b.shift();
if (rd.test(a1) || rd.test(b1)){
if (!rd.test(a1)) {
return 1;
}
if (!rd.test(b1)) {
return -1;
}
if (a1 !== b1) {
return Number(a1) - Number(b1);
}
} else {
if (a1 !== b1) {
return a1.localeCompare(b1);
}
}
}
return a.length - b.length;
}
最好将它带到一些util类中,以使其更可重用。