【问题标题】:JavsScript - Looping through Nested ArrayJavaScript - 遍历嵌套数组
【发布时间】:2021-06-16 07:55:03
【问题描述】:

我有一个嵌套的金融投资组合 JSON 文件。我需要从所有投资组合帐户的每个持股中获取 security_type(在示例 JSON 中只有一个),以及每个投资组合的每个持股的总净值,所有这些都在一个循环中。

最终,我尝试使用此信息在饼图中显示,该饼图根据证券类型的净值进行分离。

JSON 文件:

{
    "id": 1,
    "username": "Test",
    "portfolio_accounts": [
        {
            "id": 1,
            "user": 1,
            "username": "Test",
            "account_type": "IRA",
            "name": "MyTestAccount",
            "description": "Just a Test",
            "balance": 100.00,
            "holdings": [
                {
                    "id": 1,
                    "portfolio_id": 2,
                    "security_type": "Stock",
                    "ticker": "GOOG",
                    "price": 1000.50,
                    "shares": 20,
                    "purchase_date": "02-20-2021",
                    "cost_basis": 800.50
                }, 
                {
                    "id": 2,
                    "portfolio_id": 2,
                    "security_type": "Bond",
                    "ticker": "AMZN",
                    "price": 100.99,
                    "shares": 4,
                    "purchase_date": "02-20-2021",
                    "cost_basis": 60.65
                }
            ]
        },
        {
            "id": 2,
            "user": 1,
            "username": "Test",
            "account_type": "IRA",
            "name": "MyTestAccount2 - Electric Boogaloo",
            "description": "Repeat",
            "balance": 100.00,
            "holdings": [
                {
                    "id": 3,
                    "portfolio_id": 3,
                    "security_type": "Bond",
                    "ticker": "GNMA",
                    "price": 530.50,
                    "shares": 2,
                    "purchase_date": "02-20-2021",
                    "cost_basis": 40.20
                }
            ]
        }
    ]
}
  • 库存:(1000.50 * 20) = $20,010
  • 债券 1:(100.99 * 4) = $403.96
  • 债券 2:(530.50 * 2) = $1,061
  • 债券总额:1,464.96 美元

此 JSON 的预期饼图输出示例:

一个饼图,其中一种颜色代表债券 ($1,464.96),另一种颜色代表股票 ($20,010),按比例填充。如果有其他安全类型,比如加密,我需要做同样的事情并自动添加第三种颜色(依此类推)。

【问题讨论】:

  • 具体问题/疑问是什么?
  • 那么您在代码中遇到了什么问题?

标签: javascript arrays json multidimensional-array javascript-objects


【解决方案1】:

const data = 
  { id       : 1
  , username : 'Test'
  , portfolio_accounts: 
    [ { id           : 1
      , user         : 1
      , username     : 'Test'
      , account_type : 'IRA'
      , name         : 'MyTestAccount'
      , description  : 'Just a Test'
      , balance      : 100.00
      , holdings: 
        [ { id            : 1
          , portfolio_id  : 2
          , security_type : 'Stock'
          , ticker        : 'GOOG'
          , price         : 1000.50
          , shares        : 20
          , purchase_date : '02-20-2021'
          , cost_basis    : 800.50
          } 
        , { id            : 2
          , portfolio_id  : 2
          , security_type : 'Bond'
          , ticker        : 'AMZN'
          , price         : 100.99
          , shares        : 4
          , purchase_date : '02-20-2021'
          , cost_basis    : 60.65
      } ] } 
    , { id           : 2
      , user         : 1
      , username     : 'Test'
      , account_type : 'IRA'
      , name         : 'MyTestAccount2 - Electric Boogaloo'
      , description  : 'Repeat'
      , balance      : 100.00
      , holdings: 
        [ { id            : 3
          , portfolio_id  : 3
          , security_type : 'Bond'
          , ticker        : 'GNMA'
          , price         : 530.50
          , shares        : 2
          , purchase_date : '02-20-2021'
          , cost_basis    : 40.20
  } ] } ] } 
, security_types = { Stock : 0, Bond : 0 }
  ;
for(let ptfAcc of data.portfolio_accounts ) 
for(let hld    of ptfAcc.holdings )
  security_types[hld.security_type] += (hld.price * hld.shares)
  ;
console.log( security_types )

【讨论】:

    【解决方案2】:

    您可以创建一个将所有可能的证券类型设置为 0 的对象,然后将所有资产相加,例如

    let data = {
        "id": 1,
        "username": "Test",
        "portfolio_accounts": [
            {
                "id": 1,
                "user": 1,
                "username": "Test",
                "account_type": "IRA",
                "name": "MyTestAccount",
                "description": "Just a Test",
                "balance": 100.00,
                "holdings": [
                    {
                        "id": 1,
                        "portfolio_id": 2,
                        "security_type": "Stock",
                        "ticker": "GOOG",
                        "price": 1000.50,
                        "shares": 20,
                        "purchase_date": "02-20-2021",
                        "cost_basis": 800.50
                    }, 
                    {
                        "id": 2,
                        "portfolio_id": 2,
                        "security_type": "Bond",
                        "ticker": "AMZN",
                        "price": 100.99,
                        "shares": 4,
                        "purchase_date": "02-20-2021",
                        "cost_basis": 60.65
                    }
                ]
            },
            {
                "id": 2,
                "user": 1,
                "username": "Test",
                "account_type": "IRA",
                "name": "MyTestAccount2 - Electric Boogaloo",
                "description": "Repeat",
                "balance": 100.00,
                "holdings": [
                    {
                        "id": 3,
                        "portfolio_id": 3,
                        "security_type": "Bond",
                        "ticker": "GNMA",
                        "price": 530.50,
                        "shares": 2,
                        "purchase_date": "02-20-2021",
                        "cost_basis": 40.20
                    }
                ]
            }
        ]
    };
    let security_types = {
      Bond: 0,
      Stock: 0,
      Crypto: 0
    };
    data.portfolio_accounts.forEach(portfolio_account => {
      portfolio_account.holdings.forEach(holding => {
        security_types[holding.security_type] += holding.price * holding.shares;
      });
    });
    console.log(security_types);

    【讨论】:

      【解决方案3】:

      非常喜欢灵活的解决方案,所以这里有一个使用object-scan

      // const objectScan = require('object-scan');
      
      const data = { id: 1, username: 'Test', portfolio_accounts: [{ id: 1, user: 1, username: 'Test', account_type: 'IRA', name: 'MyTestAccount', description: 'Just a Test', balance: 100.00, holdings: [{ id: 1, portfolio_id: 2, security_type: 'Stock', ticker: 'GOOG', price: 1000.50, shares: 20, purchase_date: '02-20-2021', cost_basis: 800.50 }, { id: 2, portfolio_id: 2, security_type: 'Bond', ticker: 'AMZN', price: 100.99, shares: 4, purchase_date: '02-20-2021', cost_basis: 60.65 }] }, { id: 2, user: 1, username: 'Test', account_type: 'IRA', name: 'MyTestAccount2 - Electric Boogaloo', description: 'Repeat', balance: 100.00, holdings: [{ id: 3, portfolio_id: 3, security_type: 'Bond', ticker: 'GNMA', price: 530.50, shares: 2, purchase_date: '02-20-2021', cost_basis: 40.20 }] }] };
      
      const r = objectScan(['portfolio_accounts[*].holdings[*]'], {
        reverse: false,
        filterFn: ({
          value: { shares, price, security_type: securityType },
          context: { holdings, totals }
        }) => {
          const netWorth = shares * price;
          holdings.push({ [securityType]: netWorth });
          if (!(securityType in totals)) {
            totals[securityType] = 0;
          }
          totals[securityType] += netWorth;
        }
      })(data, {
        holdings: [],
        totals: {}
      });
      
      console.log(r);
      /* =>
      {
        holdings: [ { Stock: 20010 }, { Bond: 403.96 }, { Bond: 1061 } ],
        totals: { Stock: 20010, Bond: 1464.96 }
      }
       */
      .as-console-wrapper {max-height: 100% !important; top: 0}
      <script src="https://bundle.run/object-scan@14.0.0"></script>

      免责声明:我是object-scan的作者

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-28
        • 1970-01-01
        • 2021-12-28
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 2017-09-08
        • 1970-01-01
        相关资源
        最近更新 更多