Неявное приведение не может иметь дело с пробелами и недопустимыми символами в ключах объектов - PullRequest
0 голосов
/ 15 мая 2019

AlphaVantage API имеет пробелы и точки в ключах.Официального документа для API не существует, хотя вы можете увидеть его в демонстрационном URL-адресе

https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=5min&apikey=demo

В своем приложении Typescript я создал структуры данных для этого (я рад за всехскопировать и использовать их - возможно, после того, как будет найдено решение моего вопроса):

export class MetaData {
  '1. Information': string
  '2. Symbol': string
  '3. Last Refreshed': string
  '4. Output Size': string
  '5. Time Zone': string

  constructor(one, two, three, four, five) {
    this['1. Information'] = one
    this['2. Symbol'] = two
    this['3. Last Refreshed'] = three
    this['4. Output Size'] = four
    this['5. Time Zone'] = five
  }
}

export interface TimeSeries {
  [date: string]: {
    '1. open': string;
    '2. high': string;
    '3. low': string;
    '4. close': string;
    '5. volume': string;
  }
}

export interface AlphaVantage {
  'Meta Data': MetaData;
  'Time Series (Daily)'?: TimeSeries;
  'Time Series (Weekly)'?: TimeSeries;
}

Я вызываю API, используя alphavantage из NPM, и неявно приводим его к моему AlphaVantage:

const av: AlphaVantage = await alpha.data.weekly(options.stocks, 'compact', 'json')

А затем (возможно, после некоторого массажа и т. Д.) Я сохраняю его в коллекции MongoDB:

const doc = await this.model.findByIdAndUpdate(proxyModel._id, proxyModel)

(ProxyModel - это DTO, используемый для определения ключей базы данных, таких как дата, символ акции и т. Д... Одним из полей являются данные AlphaVantage).

Это должно сериализовать данные и выдает ошибки с:

key 1. Information must not contain '.'

Есть ли простой способ справиться с этим.Мой выбор - создать эквивалентные объекты без пробелов:

export interface TimeSeries {
  [date: string]: {
    '1_open': string;
    '2_high': string;
    '3_low': string;
    '4_close': string;
    '5_volume': string;
  }
}

И затем привести к этому.В этом случае предоставьте сопоставление ...

Я вижу, как я сам создаю реализацию.Однако прежде чем перейти к этому, я хотел бы услышать о любых идеях, как лучше всего справиться с этой структурой данных.

1 Ответ

0 голосов
/ 19 мая 2019

Я написал решение с помощью простой функции сопоставления ключей объекта.

Я также пытался использовать AutoMapper-ts - https://www.npmjs.com/package/automapper-ts - чтобы сделать его более понятным о внесенных изменениях. Однако стало слишком сложно составить карту всех случаев. Я не мог заставить тесты (которые действуют как doco) работать в то время, которое я выделил на это. Я только что видел, что есть https://github.com/gonza-lito/AutoMapper,, который является недавно модифицированным форком. Однако это не npm install из коробки.

Это класс, который я придумал, чтобы решить мою проблему:

export class ObjectUtils {

  static fixKey(key) {
    const upperCaseReplacer = (match: string, g1: string) => {
      return g1.toUpperCase()
    }
    const wordsReplacer = (match: string, g1: string, g2: string) => {
      return g1 + g2.toUpperCase()
    }
    const m1 = key.replace(/^\d+ *\. *([a-zA-Z])/, upperCaseReplacer)
    const m2 = m1.replace(/([a-zA-Z]) +([a-zA-Z])/g, wordsReplacer)
    const out = m2.replace(/^([a-zA-Z])/, upperCaseReplacer)
    return out
  }

  static fixObj(obj: any) {
    let newObj = null
    if (Array.isArray(obj)) {
      newObj = []
      for (const i of obj) {
        newObj.push(ObjectUtils.fixObj(i))
      }
      return newObj
    } else if (typeof obj === 'object') {
      newObj = {}
      for (const key of Object.keys(obj)) {
        newObj[ObjectUtils.fixKey(key)] = ObjectUtils.fixObj(obj[key])
      }
      return newObj
    } else {
      return obj
    }
  }
}

Это создает следующее:

export class Metadata {
  Information: string
  Symbol: string
  LastRefreshed: string
  OutputSize: string
  TimeZone: string
}

export interface TimeSeries {
  [date: string]: {
    Open: string;
    High: string;
    Low: string;
    Close: string;
    Volume: string;
  }
}

export interface AlphaVantage {
  Metadata: Metadata
  DailyTimeSeries?: TimeSeries
  WeeklyTimeSeries?: TimeSeries
}
...