我正在运行一个有角度的项目,该文件将从Firebase数据库中获取数据,而getStatistics()函数底部的代码将使用不同访问数据对的信息填充map(pairArray),数据库包含。
问题是,getStatistics()函数底部的代码(由反斜杠表示)将无法运行。好吧,在for或if-else循环中什么都不会运行。虽然console.log()函数可以工作,所以我不确定为什么代码无法运行。如果我将它放在函数中的较高位置,它将在所有计算百分比的数学下运行。
import { Component, OnInit } from '@angular/core';
// Firestore imports
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/firestore';
import {Observable,of, from, Timestamp } from 'rxjs';
//import 'rxjs/add/operator/map';
import { map } from 'rxjs/operators';
import * as firebase from 'firebase';
import { NgForm, NgModel } from '@angular/forms';
/*
getStatistics function:
The goal of this function is to iterate through the database and get the required statistics.
The structure of the database:
visits IDs are stored as collections, files, in the firestore database.
Visits of the same ID are stored as documents inside each collection.
The function iterates through each collection, ID, and counts how many visits are stored in each ID,
then it increments the AgencyCounter for each agency that was detected in the collection.
The iteration over collections and documents in the database is done by using the "payload.forEach" method
TODO
1. Identify group visits and exclude them from the getStatistics()
2. correct the common pair and common triplet algorithm. Agencies should be sorted based on how many times
they appreared in the pair or triplet visits.
*/
interface Visit{
code: number;
}
// interface that defines the agency visit structure
interface AencyVisit{
AgencyID: string;
code: string;
time: Timestamp<any>;
}
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
// Connect Agency to Firebase collection
visitCollection: AngularFirestoreCollection<Visit>;
visits: Observable<Visit[]>;
// Statistics fields
totalNumVisits = 0;
totalMultipleVisits = 0;
highest = 0;
totalNumPairVisits = 0 ;
percentageOfPairVisits = 0;
totalNumTripletVisits = 0;
percentageOfTripletVisits = 0;
totalNum5PlusVisits = 0;
lastHighest = 0;
percentageOf5PlusVisits = 0;
totalNum4Visits = 0;
percentageOf4Visits = 0;
keyHolder = "";
valueAdjuster = 0;
timer = null;
k = 0;
commonPairs = new Array();
commonPair = new Array();
commonTriplets = new Array();
commonTriplet = new Array();
values = new Array();
//this.values.push(rand = new Array());
//visitsy = new Array<Observable<Visit[]>>();
agencyCounterPerID=0;
// counterArray ={1:0, 2:0 , 3:0}; // key represents duplicate or triplet of agencies, value = their number
// 32 max agency limit per visit - hopefully no one should ever reach this
counterArray = [0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
//pairArray = new Map<Array<Object>, number>();
pairArray = new Map<string, number>();
multiples = 0;
// mostCommonPairList and mostCommonTripletList will be used to filter the most common pair and triplet agencies
mostCommonPairList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
mostCommonTripletList = {"DEMO-B-Geese":1, "DEMO-A-Berges":1, "DEMO-C1-Gentle":1, "DEMO-C2-Crunke":1,"DEMO-C3-Girls":1, "DEMO-D-Literacy":1, "DEMO-E-Life":1,"DEMO-F-Pools":1};
agencyList = new Array();
IDField: Observable<any>;
// Percentage calculations
pctMultipleAgencyVisits: number;
constructor(private afs: AngularFirestore) { }
ngOnInit(): void {
// console.log("a");
this.getStatistics();
}
getStatistics(): void{
const visitArray = this.afs.collection("visits").snapshotChanges();
visitArray.subscribe(payload => {
this.totalNumVisits = 0;
this.totalNumPairVisits = 0;
this.percentageOfPairVisits = 0;
this.totalNumTripletVisits = 0;
this.percentageOfTripletVisits = 0;
this.totalNum5PlusVisits = 0;
this.percentageOf5PlusVisits = 0;
this.totalNum4Visits = 0;
this.percentageOf4Visits = 0;
const values = [];
payload.forEach( item => {
const visit = item.payload.doc.data() as Visit;
//const values = [];
this.totalNumVisits += 1;
this.timer = null;
// getting visited frequencies
const visitedAgencies = this.afs.collection(visit.code.toString()).snapshotChanges();
visitedAgencies.subscribe(payload => {
this.agencyCounterPerID = payload.length;
this.k = 0;
payload.forEach( item => {
const agencyVisit = item.payload.doc.data() as AencyVisit;
this.agencyList.push(agencyVisit.AgencyID);
// Add visit pairs to nested list for later analysis
if (this.agencyCounterPerID == 2){
if (this.k == 0){
this.values.push(new Array(agencyVisit.AgencyID.toString()));
}
if (this.k == 1){
this.values[this.values.length - 1].push(agencyVisit.AgencyID.toString());
}
this.k = 1;
}
});
console.log("list", this.agencyList.toString());
this.counterArray[this.agencyCounterPerID]+=1;
if (this.agencyCounterPerID == 2) {
this.totalNumPairVisits += 1;
var result2 = this.agencyList.includes(this.agencyList[i]);
this.mostCommonPairList[this.agencyList[i]] += 1;
} else if (this.agencyCounterPerID == 3) {
this.totalNumTripletVisits += 1;
var result3 = this.agencyList.includes(this.agencyList[i]);
this.mostCommonTripletList[this.agencyList[i]] += 1;
} else if (this.agencyCounterPerID == 4) {
this.totalNum4Visits += 1;
} else if (this.agencyCounterPerID >= 5) {
this.totalNum5PlusVisits += 1;
}
for (var i=2; i<this.counterArray.length; i++) {
this.multiples+= this.counterArray[i];
}
// percentages
this.pctMultipleAgencyVisits = this.totalNumVisits / this.counterArray[2];//this.multiples;
this.totalMultipleVisits = this.totalNumPairVisits + this.totalNumTripletVisits + this.totalNum4Visits + this.totalNum5PlusVisits;
this.percentageOfPairVisits = this.totalNumPairVisits / this.totalMultipleVisits * 100 ;
this.percentageOfTripletVisits = this.totalNumTripletVisits / this.totalMultipleVisits * 100;
this.percentageOf4Visits = this.totalNum4Visits / this.totalMultipleVisits * 100;
this.percentageOf5PlusVisits = this.totalNum5PlusVisits / this.totalMultipleVisits * 100;
this.commonPair.push(this.agencyList[0]);
this.commonPair.push(this.agencyList[1]);
this.commonTriplet.push(this.agencyList[0]);
this.commonTriplet.push(this.agencyList[0]);
this.agencyCounterPerID =0;
//empty the array
this.agencyList.length = 0;
});
});
});
console.log("working");
/////////////////////////////////////////////////////////////////////////////
//format pairs into sorted strings
for (let u = 0; u < this.values.length; u++){
this.values[u].sort();
this.values[u].toString();
console.log("here1");
}
//add values to map(dictionary)
for (let p = 0; p < this.values.length; p++){
if (this.pairArray.has(this.values[p].toString()) == false){
this.pairArray.set(this.values[p].toString(), 1);
console.log("here2");
}
else if (this.pairArray.has(this.values[p].toString()) == true){
//return this.pairArray;
for (let a = 0; a < 10000; a++){
if (this.pairArray.get(this.values[p].toString()) == a){
this.keyHolder = this.values[p].toString();
this.valueAdjuster = a + 1;
this.pairArray.delete(this.values[p].toString());
console.log("here3");
}
console.log("here4");
}
this.pairArray.set(this.keyHolder, this.valueAdjuster);
console.log("here5");
}
}
//find number of occurences of highest frequency pair
this.highest = 0;
for (let [key, value] of this.pairArray) {
console.log("here7");
if (value > this.highest){
this.highest = value;
console.log("here6");
}
}
//add highest frequency pair to list
for (let [key, value] of this.pairArray) {
console.log("here9");
if (value == this.highest && this.commonPairs.indexOf(key) == -1){
this.commonPairs.push(key);
console.log("here8");
//break;
}
}
//find number of occurences of second highest frequency pair
this.lastHighest = this.highest;
this.highest = 0;
for (let [key, value] of this.pairArray) {
console.log("here11");
if (value > this.highest && value != this.lastHighest){
this.highest = value;
console.log("here10");
}
}
//add second highest frequency pair to list
for (let [key, value] of this.pairArray) {
console.log("here13");
if (value == this.highest && this.commonPairs.indexOf(key) == -1){
this.commonPairs.push(key);
console.log("here12");
}
}
// Prints out the dictionary
for (let [key, value] of this.pairArray) {
console.log("here14");
console.log("key: ", key.toString(), ", value: ", value);
}
console.log("end run");
/////////////////////////////////////////////////////////////////////////////
//console.log("values", this.values);
// console.log(this.counterArray[1] , " visit for " , 1 , "agencies");
// console.log(this.counterArray[2] , " visit for " , 2 , "agencies");
// console.log(this.counterArray[3] , " visit for " , 3 , "agencies");
//console.log("len", this.values.length);
//console.log("counter: ", this.counterArray);
//console.log("cp: ", typeof(this.commonPairs[0]));
//console.log("v: ", typeof(this.values[0]));
//console.log("values: ", this.values);
}
formatPercent(num) {
return Math.round(num * 100) / 100;
}
}
嗯,您的代码很多,但是看起来底部的for循环正在订阅外部调用。由于这是异步代码,因此在函数运行时,for循环中的值未定义或为空,因为尚未从firebase调用中获取值。当您调用订阅时,代码执行继续进行,同时第二个线程等待响应以执行订阅中的代码。