javascript 获取支持的货币列表

unftdfkk  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(149)

除了猜测之外(就像我下面所做的那样),有没有一种更直接、更有效的方法来反射性地检索JavaScript环境支持的所有货币的列表?

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

字符串

更新:

JavaScript规范已经通过Intl.supportedValuesOf("currency")得到了增强,提供了一种更有效的方法来直接从您的环境中检索支持的货币列表。这一添加显著简化了列出货币所需的方法,如下面更新的代码片段所示。

function getSupportedCurrencies() {
    function $(amount, currency) {
        let locale = 'en-US';
        let options = {
            style: 'currency',
            currency: currency,
            currencyDisplay: "name"
        };
        return Intl.NumberFormat(locale, options).format(amount);
    }
    let currencies = [];
    const supportedCurrencies = Intl.supportedValuesOf('currency');
    const rx = /(?<= ).+/;
    supportedCurrencies.forEach((cur) => {
        let output = $(0, cur).trim();
        let obj = {};
        obj.code = cur;
        obj.name = output.match(rx)[0];
        currencies.push(obj);
    });
    return currencies;
}
console.log(getSupportedCurrencies());


这种更新的方法消除了对货币代码的“蛮力猜测”的需要,并且它的执行速度明显更快。

mwngjboj

mwngjboj1#

现在,详尽的测试,正如公认的答案所提供的那样,可能是这里最合理的实际策略。此外,新货币不会出现,旧货币也不会以特定的频率死亡。任何实施所支持的货币都是最新的,几乎总是会反映现实。所以尝试和观察的方法真的不会失败。

但是从规范方面进一步阐述,规范实际上只关心货币是否“格式良好”:三个ASCII字母。如果生成的代码是已知的货币,你会得到合适的行为。否则,你会得到大致优雅的回退到代码本身。所以没有必要公开支持的列表:货币代码至少对许多用户来说是相对可理解的事情,因为在大多数UI中看到诸如“3 USD”或“5 CAD”之类的东西,其中涉及价格或成本,通常会暗示用户的货币。

然而,在未来,一个公开可识别货币集的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");
console.log(currencies);

字符串

3duebb1j

3duebb1j2#

您可以通过以下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;
  }, [[]]);
}

Demo

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

的字符串

相关问题