0

Component:

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

I'm using lodash to sort my array by the 'max_income' field and then applying .reverse() to sort it in descending order:

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

As seen in the screenshot above, it works perfectly other than the first row. Because it starts with an 8, it's appearing first and this is completely wrong. What adjustment can I make to force the numbers to sort properly? Here as what an object looks like:

{
    "id": 17870,
    "name": "Vitreous Mercoxit",
    "type": "Mercoxit",
    "volume": "40.00",
    "average_price": "19000.04",
    "max_income": "50,964,186",
    "image": "../assets/images/Mercoxit.png"
  }
2
  • isk is a string, try with a number instead. Commented Aug 22, 2017 at 9:21
  • You should use number instead of string in your json for volume, average_price and max_income. Commented Aug 22, 2017 at 9:21

3 Answers 3

2

I suspect the problem is it is compared as a string.

Try this:

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

or:

this.completeArray = _.sortBy(this.joinedArray,
                      (item) => {
                         return +(item.max_income.replace(',', '')); 
                      }).reverse();
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks but I'm not sure what this is doing. The order is now non-sensical: 16,189,410 - 50,964,186 - 14,863,986 - 15,117,555...
@JoeBerthelot The code I wrote returns max_income as a number, but the problem is that it does not treat commas in the string right. You can try to replace the commas with '', and then check it.
Thanks, Is there any method which support multiple column to sort in loadash?
2

The max_income is a string that can contain comma separators. Change the function that is passed to sortBy to convert the string to a number:

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

Comments

2

There's no need to use loadash here. It's better to write your own comparison function and use the native Array.sort() function.

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);

If you want a reverse sort, do b - a in the above function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.