2017-08-22 1 views
0

Komponente:Angular 2 Sortierung mit lodash

import { Component, OnInit } from '@angular/core'; 
import { HttpClient } from '@angular/common/http'; 
import * as _ from 'lodash'; 

@Component({ 
    selector: 'app-ore-table', 
    templateUrl: './ore-table.component.html', 
    styleUrls: ['./ore-table.component.less'] 
}) 
export class OreTableComponent implements OnInit { 
    ores = '../assets/json/ores.json'; 
    prices = 'https://esi.tech.ccp.is/latest/markets/prices/?datasource=tranquility'; 

    oreArray: any; 
    pricesArray: any; 
    joinedArray: Array<any> = []; 
    completeArray: Array<any> = []; 

    seconds: number; 
    turrets: any; 
    turretYield: any; 
    duration: any; 

    constructor(private http: HttpClient) { 
    this.seconds = 3600; 
    this.turrets = 2; 
    this.turretYield = 1593; 
    this.duration = 106.9; 
    } 

    getOres() { 
    this.http.get(this.ores).subscribe(data => { 
     this.oreArray = data; 
     this.getPrices(); 
    }); 
    } 

    getPrices() { 
    this.http.get(this.prices).subscribe(data => { 
     this.pricesArray = data; 
     this.joinPrices(); 
    }); 
    } 

    joinPrices() { 
    const cycles = this.seconds/this.duration; 
    const totalYield = this.turretYield * this.turrets; 

    this.oreArray.forEach((data) => { 
     const matchingPrice = this.getMatchingPrice(data); 

     const oreMined = totalYield * (1/data.volume) * cycles; 
     const hourIncome = matchingPrice.average_price.toFixed(2) * oreMined; 
     const hourIncomeFormat = Number(hourIncome).toFixed(); 
     const isk = String(hourIncomeFormat).replace(/(.)(?=(\d{3})+$)/g, '$1,'); 

     if (matchingPrice !== false) { 
      this.joinedArray.push({ 
       id: data.id, 
       name: data.name, 
       type: data.type, 
       volume: data.volume.toFixed(2), 
       average_price: matchingPrice.average_price.toFixed(2), 
       max_income: isk, 
       image: data.image 
      }); 
     } 
    }); 
    console.log(this.joinedArray); 
    this.completeArray = _.sortBy(this.joinedArray, ['max_income']).reverse(); 
    } 

    updatePrices(newTurrets, newTurretYield, newDuration) { 
    console.log(newTurrets); 
    this.joinedArray = []; 

    const cycles = this.seconds/newDuration; 
    const totalYield = newTurretYield * newTurrets; 

    this.oreArray.forEach((data) => { 
     const matchingPrice = this.getMatchingPrice(data); 

     const oreMined = totalYield * (1/data.volume) * cycles; 
     const hourIncome = matchingPrice.average_price.toFixed(2) * oreMined; 
     const hourIncomeFormat = Number(hourIncome).toFixed(); 
     const isk = String(hourIncomeFormat).replace(/(.)(?=(\d{3})+$)/g, '$1,'); 

     if (matchingPrice !== false) { 
      this.joinedArray.push({ 
       id: data.id, 
       name: data.name, 
       type: data.type, 
       volume: data.volume.toFixed(2), 
       average_price: matchingPrice.average_price.toFixed(2), 
       max_income: isk, 
       image: data.image 
      }); 
     } 
    }); 
    } 

    getMatchingPrice(data) { 
    for (let i = 0; i < this.pricesArray.length; i++) { 
     if (this.pricesArray[i].type_id === data.id) { 
      return this.pricesArray[i]; 
     } 
    } 
    return false; 
    } 

    ngOnInit() { 
    this.getOres(); 
    } 
} 

HTML:

<tr *ngFor="let ore of completeArray" id="{{ ore.id }}"> 
     <td><img src="{{ ore.image }}" alt="{{ ore.name}}" /></td> 
     <td><strong>{{ ore.name }}</strong></td> 
     <td class="right aligned">{{ ore.volume }} m&#179;</td> 
     <td class="right aligned">{{ ore.average_price }} ISK</td> 
     <td class="right aligned">{{ ore.max_income }}</td> 
     </tr> 

Screenshot:

enter image description here

Ich verwende lodash mein Array von der 'max_income' Feld zu sortieren und dann .reverse() anwenden, um es in absteigender Reihenfolge zu sortieren rder:

this.completeArray = _.sortBy(this.joinedArray, ['max_income']).reverse(); 

Wie auf dem Screenshot oben gesehen, funktioniert es perfekt anders als die erste Zeile. Weil es mit einer 8 beginnt, erscheint es zuerst und das ist völlig falsch. Welche Anpassung kann ich vornehmen, um die Zahlen richtig zu sortieren? Wie ein Objekt aussieht:

{ 
    "id": 17870, 
    "name": "Vitreous Mercoxit", 
    "type": "Mercoxit", 
    "volume": "40.00", 
    "average_price": "19000.04", 
    "max_income": "50,964,186", 
    "image": "../assets/images/Mercoxit.png" 
    } 
+0

ISK ist eine Zeichenfolge, versuchen Sie stattdessen mit einer Zahl. – Hosar

+0

Sie sollten in Ihrem JSON die Nummer anstelle von string für Volumen, average_price und max_income verwenden. –

Antwort

1

Ich vermute, das Problem ist, dass es als eine Zeichenfolge verglichen wird.

Versuchen Sie folgendes:

this.completeArray = _.sortBy(this.joinedArray, 
        (item) => { 
        return +item.max_income; 
        }).reverse(); 

oder:

this.completeArray = _.sortBy(this.joinedArray, 
         (item) => { 
         return +(item.max_income.replace(',', '')); 
         }).reverse(); 
+0

Danke, aber ich bin nicht sicher, was das tut. Die Reihenfolge ist jetzt unsensibel: 16.189.410 - 50.964.186 - 14.863.986 - 15.117.555 ... –

+0

@JoeBerthelot Der Code, den ich schrieb, gibt max_income als Zahl zurück, aber das Problem ist, dass Kommas in der Zeichenfolge nicht richtig behandelt werden. Sie können versuchen, die Kommata durch '' zu ersetzen, und dann überprüfen Sie es. – Matsura

2

Es gibt keine Notwendigkeit loadash hier zu verwenden. Es ist besser, eine eigene Vergleichsfunktion zu schreiben und die native Array.sort()-Funktion zu verwenden.

var numberCompare = (a, b) => a - b; 
 

 
var arr = ['1', '20', '31', '400,000', '5', '600', '70']; 
 
var res = arr.map(x => +x.replace(',', '')).sort(numberCompare); 
 

 
console.log(res);

Wenn Sie eine umgekehrte Art wollen, tun b - a in der obigen Funktion.

1

Die max_income ist eine Zeichenfolge, die Kommatrennzeichen enthalten kann. Ändern Sie die an sortBy übergebene Funktion, um die Zeichenfolge in eine Zahl zu konvertieren:

_.sortBy(this.joinedArray, item => +item.max_income.replace(',', ''))