获取支持的货币列表

Get List of Supported Currencies

除了猜测(就像我在下面所做的那样)之外,是否有更直接和有效的方法反射性地检索您的 [=21] 支持的所有货币的列表=] 环境?

function getSupportedCurrencies() {
  function $(amount, currency) {
    let locale = 'en-US';
    let options = {
      style: 'currency',
      currency: currency,
      currencyDisplay: "name"
    };
    return Intl.NumberFormat(locale, options).format(amount);
  }
  const getAllPossibleThreeLetterWords = () => {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const arr = [];
    let text = '';
    for (let i = 0; i < chars.length; i++) {
      for (let x = 0; x < chars.length; x++) {
        for (let j = 0; j < chars.length; j++) {
          text += chars[i];
          text += chars[x];
          text += chars[j];
          arr.push(text);
          text = '';
        }
      }
    }
    return arr;
  };
  let ary = getAllPossibleThreeLetterWords();
  let currencies = [];
  const rx = /(?<= ).+/; // This line doesn't work in Firefox versions older than version 78 due to bug 1225665: https://bugzilla.mozilla.org/show_bug.cgi?id=1225665
  ary.forEach((cur) => {
    let output = $(0, cur).trim();
    if (output.replace(/^[^ ]+ /, '') !== cur) {
      let obj = {};
      obj.code = cur;
      obj.name = output.match(rx)[0];
      currencies.push(obj);
    }
  });
  return currencies;
}
console.log(getSupportedCurrencies());

您可以通过此 XML:

加载已知列表

https://www.currency-iso.org/dam/downloads/lists/list_one.xml

列表是在此处找到的:https://www.currency-iso.org/en/home/tables/table-a1.html

<ISO_4217 Pblshd="2018-08-29">
  <CcyTbl>
    <CcyNtry>
      <CtryNm>
        UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND (THE)
      </CtryNm>
      <CcyNm>Pound Sterling</CcyNm>
      <Ccy>GBP</Ccy>
      <CcyNbr>826</CcyNbr>
      <CcyMnrUnts>2</CcyMnrUnts>
    </CcyNtry>
    <CcyNtry>
      <CtryNm>UNITED STATES OF AMERICA (THE)</CtryNm>
      <CcyNm>US Dollar</CcyNm>
      <Ccy>USD</Ccy>
      <CcyNbr>840</CcyNbr>
      <CcyMnrUnts>2</CcyMnrUnts>
    </CcyNtry>
  </CcyTbl>
</ISO_4217>

var xmlString = getSampleCurrencyXml();
var xmlData = (new window.DOMParser()).parseFromString(xmlString, "text/xml");
var knownCodes = [].slice.call(xmlData.querySelectorAll('Ccy')).map(n => n.textContent)

// Fetch the XML instead?
fetch('https://www.currency-iso.org/dam/downloads/lists/list_one.xml', { cache: 'default' })
  .then(response => response.text())
  .then(xmlStr => (new window.DOMParser()).parseFromString(xmlStr, "text/xml"))
  .then(data => knownCodes = data); // This may not work in the Stack Snippet

console.log(getSupportedCurrencies().map(c => c.code + '\t' + c.name).join('\n'));

function getSupportedCurrencies() {
  function $(amount, currency) {
    return Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: currency,
      currencyDisplay: 'name'
    }).format(amount);
  }
  return knownCodes.reduce((currencies, cur) => {
    return (output => {
      return output.replace(/^[^ ]+ /, '') !== cur ?
        currencies.concat({
          code: cur,
          name: output.match(/(?<= ).+/)[0]
        }) :
        currencies;
    })($(0, cur).trim());
  }, []);
}

function getSampleCurrencyXml() {
  return `
    <ISO_4217 Pblshd="2018-08-29">
      <CcyTbl>
        <CcyNtry>
          <CtryNm>
            UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND (THE)
          </CtryNm>
          <CcyNm>Pound Sterling</CcyNm>
          <Ccy>GBP</Ccy>
          <CcyNbr>826</CcyNbr>
          <CcyMnrUnts>2</CcyMnrUnts>
        </CcyNtry>
        <CcyNtry>
          <CtryNm>UNITED STATES OF AMERICA (THE)</CtryNm>
          <CcyNm>US Dollar</CcyNm>
          <Ccy>USD</Ccy>
          <CcyNbr>840</CcyNbr>
          <CcyMnrUnts>2</CcyMnrUnts>
        </CcyNtry>
      </CcyTbl>
    </ISO_4217>
  `;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }


如果你仍然想生成代码,你可以使用可迭代的产品。

以下内容基于Python的itertools.product函数。

let ary = product('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), 3).map(a => a.join(''));

function product(iterables, repeat) {
  var argv = Array.prototype.slice.call(arguments), argc = argv.length;
  if (argc === 2 && !isNaN(argv[argc - 1])) {
    var copies = [];
    for (var i = 0; i < argv[argc - 1]; i++) { copies.push(argv[0].slice()); }
    argv = copies;
  }
  return argv.reduce((accumulator, value) => {
    var tmp = [];
    accumulator.forEach(a0 => value.forEach(a1 => tmp.push(a0.concat(a1))));
    return tmp;
  }, [[]]);
}

演示

console.log(getSupportedCurrencies().map(c => c.code + '\t' + c.name).join('\n'));

function getSupportedCurrencies() {
  function $(amount, currency) {
    return Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: currency,
      currencyDisplay: 'name'
    }).format(amount);
  }
  let ary = product('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), 3).map(a => a.join(''));
  return ary.reduce((currencies, cur) => {
    return (output => {
      return output.replace(/^[^ ]+ /, '') !== cur
        ? currencies.concat({ code : cur, name : output.match(/(?<= ).+/)[0] })
        : currencies;
    })($(0, cur).trim());
  }, []);
}

function product(iterables, repeat) {
  var argv = Array.prototype.slice.call(arguments), argc = argv.length;
  if (argc === 2 && !isNaN(argv[argc - 1])) {
    var copies = [];
    for (var i = 0; i < argv[argc - 1]; i++) { copies.push(argv[0].slice()); }
    argv = copies;
  }
  return argv.reduce((accumulator, value) => {
    var tmp = [];
    accumulator.forEach(a0 => value.forEach(a1 => tmp.push(a0.concat(a1))));
    return tmp;
  }, [[]]);
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

现在,正如公认的答案所提供的那样,详尽的测试可能是这里最合理的实用策略。此外,新货币不会出现,旧货币不会消亡,而且频率特别高。任何实施所支持的货币都保持最新,几乎总是会反映现实。所以试一试的方法真的不会失败。

但要从规范方面进一步详细说明,规范实际上只关心货币是否“格式正确”:三个 ASCII 字母。如果生成的代码是一种已知货币,您将获得意想不到的行为。否则,您将大致优雅地回退到代码本身。因此 有争议 不需要公开支持的列表:货币代码对许多用户来说至少是一个相对容易理解的东西,可能就像大多数 UI 看到类似“3美元”或“5 加元”(其中涉及价格或成本)通常表示用户的货币。

在未来,然而,公开公认货币集的spec proposal正朝着标准化的方向发展。初始实现可能会在 2021 年底之前开始出现在 Web 浏览器的 JS 实现中,让你这样做:

// This will return an array of currency codes supported
// by Intl.NumberFormat and Intl.DisplayNames, e.g.:
//   ["ADP", "AED", ..., "JPY", ..., "USD", ...]
var currencies = Intl.supportedValuesOf("currency");