-1

I am trying to apply ramda in my nodejs backend to do a concatenation of objects but I have not been able to establish the relationship of the objects when they are equal.

Here I show you the first arrangement:

{
  "ETHBTC": "0.03907000",
  "LTCBTC": "0.00481700",
  "BNBBTC": "0.00901600",
  "NEOBTC": "0.00200600",
  "QTUMETH": "0.00902000",
  "EOSETH": "0.00310500",
  "SNTETH": "0.00008902",
  "BNTETH": "0.00308500",
  "BCCBTC": "0.07908100",
  "GASBTC": "0.00032410",
  "BNBETH": "0.23078000",
  "BTCUSDT": "55974.56000000",
  "ETHUSDT": "2186.71000000",
  "HSRBTC": "0.00041400",
  "OAXETH": "0.00017780",
  "DNTETH": "0.00002801",
  "MCOETH": "0.00577200"
}

Here I show you the second arrangement:

[
  {
    "asset": "BTC",
    "free": "0.01054959",
    "locked": "0.00000000"
  },
  {
    "asset": "LTC",
    "free": "0.00000000",
    "locked": "0.00000000"
  },
  {
    "asset": "ETH",
    "free": "0.00000000",
    "locked": "0.00000000"
  }
]

Here I show you the third arrangement:

[
  {
    "symbol": "ETHBTC",
    "status": "TRADING",
    "baseAsset": "ETH",
    "baseAssetPrecision": 8,
    "quoteAsset": "BTC",
    "quotePrecision": 8,
    "quoteAssetPrecision": 8,
    "baseCommissionPrecision": 8,
    "quoteCommissionPrecision": 8,
    "orderTypes": [
      "LIMIT",
      "LIMIT_MAKER",
      "MARKET",
      "STOP_LOSS_LIMIT",
      "TAKE_PROFIT_LIMIT"
    ],
    "icebergAllowed": true,
    "ocoAllowed": true,
    "quoteOrderQtyMarketAllowed": true,
    "isSpotTradingAllowed": true,
    "isMarginTradingAllowed": true,
    "filters": [
      {
        "filterType": "PRICE_FILTER",
        "minPrice": "0.00000100",
        "maxPrice": "100000.00000000",
        "tickSize": "0.00000100"
      },
      {
        "filterType": "PERCENT_PRICE",
        "multiplierUp": "5",
        "multiplierDown": "0.2",
        "avgPriceMins": 5
      },
      {
        "filterType": "LOT_SIZE",
        "minQty": "0.00100000",
        "maxQty": "100000.00000000",
        "stepSize": "0.00100000"
      },
      {
        "filterType": "MIN_NOTIONAL",
        "minNotional": "0.00010000",
        "applyToMarket": true,
        "avgPriceMins": 5
      },
      {
        "filterType": "ICEBERG_PARTS",
        "limit": 10
      },
      {
        "filterType": "MARKET_LOT_SIZE",
        "minQty": "0.00000000",
        "maxQty": "1784.90123628",
        "stepSize": "0.00000000"
      },
      {
        "filterType": "MAX_NUM_ORDERS",
        "maxNumOrders": 200
      },
      {
        "filterType": "MAX_NUM_ALGO_ORDERS",
        "maxNumAlgoOrders": 5
      }
    ],
    "permissions": [
      "SPOT",
      "MARGIN"
    ]
  },
  {
    "symbol": "LTCBTC",
    "status": "TRADING",
    "baseAsset": "LTC",
    "baseAssetPrecision": 8,
    "quoteAsset": "BTC",
    "quotePrecision": 8,
    "quoteAssetPrecision": 8,
    "baseCommissionPrecision": 8,
    "quoteCommissionPrecision": 8,
    "orderTypes": [
      "LIMIT",
      "LIMIT_MAKER",
      "MARKET",
      "STOP_LOSS_LIMIT",
      "TAKE_PROFIT_LIMIT"
    ],
    "icebergAllowed": true,
    "ocoAllowed": true,
    "quoteOrderQtyMarketAllowed": true,
    "isSpotTradingAllowed": true,
    "isMarginTradingAllowed": true,
    "filters": [
      {
        "filterType": "PRICE_FILTER",
        "minPrice": "0.00000100",
        "maxPrice": "100000.00000000",
        "tickSize": "0.00000100"
      },
      {
        "filterType": "PERCENT_PRICE",
        "multiplierUp": "5",
        "multiplierDown": "0.2",
        "avgPriceMins": 5
      },
      {
        "filterType": "LOT_SIZE",
        "minQty": "0.01000000",
        "maxQty": "100000.00000000",
        "stepSize": "0.01000000"
      },
      {
        "filterType": "MIN_NOTIONAL",
        "minNotional": "0.00010000",
        "applyToMarket": true,
        "avgPriceMins": 5
      },
      {
        "filterType": "ICEBERG_PARTS",
        "limit": 10
      },
      {
        "filterType": "MARKET_LOT_SIZE",
        "minQty": "0.00000000",
        "maxQty": "10633.87362057",
        "stepSize": "0.00000000"
      },
      {
        "filterType": "MAX_NUM_ORDERS",
        "maxNumOrders": 200
      },
      {
        "filterType": "MAX_NUM_ALGO_ORDERS",
        "maxNumAlgoOrders": 5
      }
    ],
    "permissions": [
      "SPOT",
      "MARGIN"
    ]
  },
  {
    "symbol": "BNBBTC",
    "status": "TRADING",
    "baseAsset": "BNB",
    "baseAssetPrecision": 8,
    "quoteAsset": "BTC",
    "quotePrecision": 8,
    "quoteAssetPrecision": 8,
    "baseCommissionPrecision": 8,
    "quoteCommissionPrecision": 8,
    "orderTypes": [
      "LIMIT",
      "LIMIT_MAKER",
      "MARKET",
      "STOP_LOSS_LIMIT",
      "TAKE_PROFIT_LIMIT"
    ],
    "icebergAllowed": true,
    "ocoAllowed": true,
    "quoteOrderQtyMarketAllowed": true,
    "isSpotTradingAllowed": true,
    "isMarginTradingAllowed": true,
    "filters": [
      {
        "filterType": "PRICE_FILTER",
        "minPrice": "0.00000010",
        "maxPrice": "100000.00000000",
        "tickSize": "0.00000010"
      },
      {
        "filterType": "PERCENT_PRICE",
        "multiplierUp": "5",
        "multiplierDown": "0.2",
        "avgPriceMins": 5
      },
      {
        "filterType": "LOT_SIZE",
        "minQty": "0.01000000",
        "maxQty": "100000.00000000",
        "stepSize": "0.01000000"
      },
      {
        "filterType": "MIN_NOTIONAL",
        "minNotional": "0.00010000",
        "applyToMarket": true,
        "avgPriceMins": 5
      },
      {
        "filterType": "ICEBERG_PARTS",
        "limit": 10
      },
      {
        "filterType": "MARKET_LOT_SIZE",
        "minQty": "0.00000000",
        "maxQty": "3604.01847116",
        "stepSize": "0.00000000"
      },
      {
        "filterType": "MAX_NUM_ORDERS",
        "maxNumOrders": 200
      },
      {
        "filterType": "MAX_NUM_ALGO_ORDERS",
        "maxNumAlgoOrders": 5
      }
    ],
    "permissions": [
      "SPOT",
      "MARGIN"
    ]
  },
{
    "symbol": "BTCUSDT",
    "status": "TRADING",
    "baseAsset": "BTC",
    "baseAssetPrecision": 8,
    "quoteAsset": "USDT",
    "quotePrecision": 8,
    "quoteAssetPrecision": 8,
    "baseCommissionPrecision": 8,
    "quoteCommissionPrecision": 8,
    "orderTypes": [
      "LIMIT",
      "LIMIT_MAKER",
      "MARKET",
      "STOP_LOSS_LIMIT",
      "TAKE_PROFIT_LIMIT"
    ],
    "icebergAllowed": true,
    "ocoAllowed": true,
    "quoteOrderQtyMarketAllowed": true,
    "isSpotTradingAllowed": true,
    "isMarginTradingAllowed": true,
    "filters": [
      {
        "filterType": "PRICE_FILTER",
        "minPrice": "0.01000000",
        "maxPrice": "1000000.00000000",
        "tickSize": "0.01000000"
      },
      {
        "filterType": "PERCENT_PRICE",
        "multiplierUp": "5",
        "multiplierDown": "0.2",
        "avgPriceMins": 5
      },
      {
        "filterType": "LOT_SIZE",
        "minQty": "0.00000100",
        "maxQty": "9000.00000000",
        "stepSize": "0.00000100"
      },
      {
        "filterType": "MIN_NOTIONAL",
        "minNotional": "10.00000000",
        "applyToMarket": true,
        "avgPriceMins": 5
      },
      {
        "filterType": "ICEBERG_PARTS",
        "limit": 10
      },
      {
        "filterType": "MARKET_LOT_SIZE",
        "minQty": "0.00000000",
        "maxQty": "82.65659251",
        "stepSize": "0.00000000"
      },
      {
        "filterType": "MAX_NUM_ORDERS",
        "maxNumOrders": 200
      },
      {
        "filterType": "MAX_NUM_ALGO_ORDERS",
        "maxNumAlgoOrders": 5
      }
    ],
    "permissions": [
      "SPOT",
      "MARGIN"
    ]
  }
]

What I have to do is first take the asset value from the second array and look for its symbol in the third array.

Once I know what its symbol is, with this symbol I look for its information (asset, free, locked) in the third array, being the symbol (second array) === asset (third array).

Once I have the information of a currency in the three arrays, there I must merge the data in the first array with the second array (the value of the first array must be changed to cost)

Here I show you the desired result:

[
   {
    "asset": "BTC",
    "free": "0.01054959",
    "locked": "0.00000000",
    "cost": "55974.56000000"
  },
  {
    "asset": "LTC",
    "free": "0.00000000",
    "locked": "0.00000000",
    "cost": "0.00481700"
  },
  {
    "asset": "ETH",
    "free": "0.00000000",
    "locked": "0.00000000",
    "cost": "0.03907000"
  }
]

2 Answers2

2

Solution using Javascript Map

I would recommend creating a Map out of zs array which maps baseAsset to symbol.

And then looping over ys and constructing the cost field using the Map and the xs array.

const 
   xs = {ETHBTC: "0.03907000", LTCBTC: "0.00481700", BNBBTC: "0.00901600", NEOBTC: "0.00200600", QTUMETH: "0.00902000", EOSETH: "0.00310500", SNTETH: "0.00008902", BNTETH: "0.00308500", BCCBTC: "0.07908100", GASBTC: "0.00032410", BNBETH: "0.23078000", BTCUSDT: "55974.56000000", ETHUSDT: "2186.71000000", HSRBTC: "0.00041400", OAXETH: "0.00017780", DNTETH: "0.00002801", MCOETH: "0.00577200"},
   ys = [{asset: "BTC", free: "0.01054959", locked: "0.00000000"}, {asset: "LTC", free: "0.00000000", locked: "0.00000000"}, {asset: "ETH", free: "0.00000000", locked: "0.00000000"}],
   zs = [{symbol: "ETHBTC", status: "TRADING", baseAsset: "ETH", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00100000", maxQty: "100000.00000000", stepSize: "0.00100000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "1784.90123628", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "LTCBTC", status: "TRADING", baseAsset: "LTC", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "10633.87362057", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BNBBTC", status: "TRADING", baseAsset: "BNB", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000010", maxPrice: "100000.00000000", tickSize: "0.00000010"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "3604.01847116", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BTCUSDT", status: "TRADING", baseAsset: "BTC", baseAssetPrecision: 8, quoteAsset: "USDT", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.01000000", maxPrice: "1000000.00000000", tickSize: "0.01000000"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00000100", maxQty: "9000.00000000", stepSize: "0.00000100"}, {filterType: "MIN_NOTIONAL", minNotional: "10.00000000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "82.65659251", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}],
      
   zsMap = new Map(zs.map(({baseAsset, symbol}) => [baseAsset, symbol])),
   desired = ys.map(o => ({...o, cost: xs[zsMap.get(o.asset)]}))

console.log(desired)

Same solution but using IIFE

const 
   xs = {ETHBTC: "0.03907000", LTCBTC: "0.00481700", BNBBTC: "0.00901600", NEOBTC: "0.00200600", QTUMETH: "0.00902000", EOSETH: "0.00310500", SNTETH: "0.00008902", BNTETH: "0.00308500", BCCBTC: "0.07908100", GASBTC: "0.00032410", BNBETH: "0.23078000", BTCUSDT: "55974.56000000", ETHUSDT: "2186.71000000", HSRBTC: "0.00041400", OAXETH: "0.00017780", DNTETH: "0.00002801", MCOETH: "0.00577200"},
   ys = [{asset: "BTC", free: "0.01054959", locked: "0.00000000"}, {asset: "LTC", free: "0.00000000", locked: "0.00000000"}, {asset: "ETH", free: "0.00000000", locked: "0.00000000"}],
   zs = [{symbol: "ETHBTC", status: "TRADING", baseAsset: "ETH", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00100000", maxQty: "100000.00000000", stepSize: "0.00100000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "1784.90123628", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "LTCBTC", status: "TRADING", baseAsset: "LTC", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "10633.87362057", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BNBBTC", status: "TRADING", baseAsset: "BNB", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000010", maxPrice: "100000.00000000", tickSize: "0.00000010"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "3604.01847116", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BTCUSDT", status: "TRADING", baseAsset: "BTC", baseAssetPrecision: 8, quoteAsset: "USDT", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.01000000", maxPrice: "1000000.00000000", tickSize: "0.01000000"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00000100", maxQty: "9000.00000000", stepSize: "0.00000100"}, {filterType: "MIN_NOTIONAL", minNotional: "10.00000000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "82.65659251", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}],
  
   desired = ((zsMap) =>
     ys.map(o => ({ ...o, cost: xs[zsMap.get(o.asset)] })))(
     new Map(zs.map(({ baseAsset, symbol }) => [baseAsset, symbol]))
   );

console.log(desired);
Som Shekhar Mukherjee
  • 4,701
  • 1
  • 12
  • 28
1

My first approach wouldn't use Ramda, as this seems fairly straightforward in vanilla JS:

const combine = (xs, ys, zs) => 
  ys .map ((
    {asset, ...rest}, _i, _arr, 
    {symbol = ''} = zs .find (({baseAsset}) => baseAsset == asset),
    cost = xs [symbol]
  ) => ({asset, ...rest, cost}))

const xs = {ETHBTC: "0.03907000", LTCBTC: "0.00481700", BNBBTC: "0.00901600", NEOBTC: "0.00200600", QTUMETH: "0.00902000", EOSETH: "0.00310500", SNTETH: "0.00008902", BNTETH: "0.00308500", BCCBTC: "0.07908100", GASBTC: "0.00032410", BNBETH: "0.23078000", BTCUSDT: "55974.56000000", ETHUSDT: "2186.71000000", HSRBTC: "0.00041400", OAXETH: "0.00017780", DNTETH: "0.00002801", MCOETH: "0.00577200"}
const ys = [{asset: "BTC", free: "0.01054959", locked: "0.00000000"}, {asset: "LTC", free: "0.00000000", locked: "0.00000000"}, {asset: "ETH", free: "0.00000000", locked: "0.00000000"}]
const zs = [{symbol: "ETHBTC", status: "TRADING", baseAsset: "ETH", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00100000", maxQty: "100000.00000000", stepSize: "0.00100000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "1784.90123628", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "LTCBTC", status: "TRADING", baseAsset: "LTC", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "10633.87362057", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BNBBTC", status: "TRADING", baseAsset: "BNB", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000010", maxPrice: "100000.00000000", tickSize: "0.00000010"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "3604.01847116", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BTCUSDT", status: "TRADING", baseAsset: "BTC", baseAssetPrecision: 8, quoteAsset: "USDT", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.01000000", maxPrice: "1000000.00000000", tickSize: "0.01000000"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00000100", maxQty: "9000.00000000", stepSize: "0.00000100"}, {filterType: "MIN_NOTIONAL", minNotional: "10.00000000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "82.65659251", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}]

console .log (combine (xs, ys, zs))
.as-console-wrapper {max-height: 100% !important; top: 0}

We map the elements of your second array, keeping all their properties and searching the third array for a record whose baseAsset equals the asset of the current node, then look up this new record's symbol property in the first array.

The style may feel unfamiliar. I much prefer working with expressions rather than statements, so I use additional defaulted parameters rather than local variables. This requires supplying dummy values for the extra arguments Array.prototype.map supplies to its callback. That's _i and _arr.

While it might be interesting to see if there's a cleaner Ramda version, I'm not particularly hopeful. Ramda's map function would improve this a bit, because it wouldn't need _i and _arr, but that's fairly minor.

Update

Som Shekhar Mukherjee makes a good point about using a Map to avoid repeated searches of the second list. This version does that, keeping the Map around only for the call to combine. But of course if you needed to do this multiple times, you might want to store that Map externally, and pass it in place of zs. The design is as before except this time we add a new defaulted parameter map to the initial call.

const combine = (xs, ys, zs, map = new Map (zs .map (({baseAsset, symbol}) => [baseAsset, symbol]))) => 
  ys .map ((
    {asset, ...rest}, _i, _arr, 
    cost = xs [map .get (asset)]
  ) => ({asset, ...rest, cost}))


const xs = {ETHBTC: "0.03907000", LTCBTC: "0.00481700", BNBBTC: "0.00901600", NEOBTC: "0.00200600", QTUMETH: "0.00902000", EOSETH: "0.00310500", SNTETH: "0.00008902", BNTETH: "0.00308500", BCCBTC: "0.07908100", GASBTC: "0.00032410", BNBETH: "0.23078000", BTCUSDT: "55974.56000000", ETHUSDT: "2186.71000000", HSRBTC: "0.00041400", OAXETH: "0.00017780", DNTETH: "0.00002801", MCOETH: "0.00577200"}
const ys = [{asset: "BTC", free: "0.01054959", locked: "0.00000000"}, {asset: "LTC", free: "0.00000000", locked: "0.00000000"}, {asset: "ETH", free: "0.00000000", locked: "0.00000000"}]
const zs = [{symbol: "ETHBTC", status: "TRADING", baseAsset: "ETH", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00100000", maxQty: "100000.00000000", stepSize: "0.00100000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "1784.90123628", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "LTCBTC", status: "TRADING", baseAsset: "LTC", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "10633.87362057", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BNBBTC", status: "TRADING", baseAsset: "BNB", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000010", maxPrice: "100000.00000000", tickSize: "0.00000010"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "3604.01847116", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BTCUSDT", status: "TRADING", baseAsset: "BTC", baseAssetPrecision: 8, quoteAsset: "USDT", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.01000000", maxPrice: "1000000.00000000", tickSize: "0.01000000"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00000100", maxQty: "9000.00000000", stepSize: "0.00000100"}, {filterType: "MIN_NOTIONAL", minNotional: "10.00000000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "82.65659251", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}]

console .log (
  combine (xs, ys, zs)
)
.as-console-wrapper {max-height: 100% !important; top: 0}

(I also modified the handling of the named properties from xs, inspired again by Som.)

Update 2

I did the last one in too much of a hurry. Now with cost so easy to find, we don't need the extra map callback parameter either, and this becomes simpler still:

const combine = (xs, ys, zs, 
  map = new Map (zs .map (({baseAsset, symbol}) => [baseAsset, symbol]))
) => 
  ys .map (({asset, ...rest}) => ({asset, ...rest, cost: xs [map .get (asset)]}))


const xs = {ETHBTC: "0.03907000", LTCBTC: "0.00481700", BNBBTC: "0.00901600", NEOBTC: "0.00200600", QTUMETH: "0.00902000", EOSETH: "0.00310500", SNTETH: "0.00008902", BNTETH: "0.00308500", BCCBTC: "0.07908100", GASBTC: "0.00032410", BNBETH: "0.23078000", BTCUSDT: "55974.56000000", ETHUSDT: "2186.71000000", HSRBTC: "0.00041400", OAXETH: "0.00017780", DNTETH: "0.00002801", MCOETH: "0.00577200"}
const ys = [{asset: "BTC", free: "0.01054959", locked: "0.00000000"}, {asset: "LTC", free: "0.00000000", locked: "0.00000000"}, {asset: "ETH", free: "0.00000000", locked: "0.00000000"}]
const zs = [{symbol: "ETHBTC", status: "TRADING", baseAsset: "ETH", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00100000", maxQty: "100000.00000000", stepSize: "0.00100000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "1784.90123628", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "LTCBTC", status: "TRADING", baseAsset: "LTC", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000100", maxPrice: "100000.00000000", tickSize: "0.00000100"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "10633.87362057", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BNBBTC", status: "TRADING", baseAsset: "BNB", baseAssetPrecision: 8, quoteAsset: "BTC", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.00000010", maxPrice: "100000.00000000", tickSize: "0.00000010"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.01000000", maxQty: "100000.00000000", stepSize: "0.01000000"}, {filterType: "MIN_NOTIONAL", minNotional: "0.00010000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "3604.01847116", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}, {symbol: "BTCUSDT", status: "TRADING", baseAsset: "BTC", baseAssetPrecision: 8, quoteAsset: "USDT", quotePrecision: 8, quoteAssetPrecision: 8, baseCommissionPrecision: 8, quoteCommissionPrecision: 8, orderTypes: ["LIMIT", "LIMIT_MAKER", "MARKET", "STOP_LOSS_LIMIT", "TAKE_PROFIT_LIMIT"], icebergAllowed: true, ocoAllowed: true, quoteOrderQtyMarketAllowed: true, isSpotTradingAllowed: true, isMarginTradingAllowed: true, filters: [{filterType: "PRICE_FILTER", minPrice: "0.01000000", maxPrice: "1000000.00000000", tickSize: "0.01000000"}, {filterType: "PERCENT_PRICE", multiplierUp: "5", multiplierDown: "0.2", avgPriceMins: 5}, {filterType: "LOT_SIZE", minQty: "0.00000100", maxQty: "9000.00000000", stepSize: "0.00000100"}, {filterType: "MIN_NOTIONAL", minNotional: "10.00000000", applyToMarket: true, avgPriceMins: 5}, {filterType: "ICEBERG_PARTS", limit: 10}, {filterType: "MARKET_LOT_SIZE", minQty: "0.00000000", maxQty: "82.65659251", stepSize: "0.00000000"}, {filterType: "MAX_NUM_ORDERS", maxNumOrders: 200}, {filterType: "MAX_NUM_ALGO_ORDERS", maxNumAlgoOrders: 5}], permissions: ["SPOT", "MARGIN"]}]

console .log (
  combine (xs, ys, zs)
)
.as-console-wrapper {max-height: 100% !important; top: 0}
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Hey Scott! I would prefer using `Map` instead of finding in the array again and again, which could be bad in terms of performance if the array is of considerable length. Could you please review my solution? – Som Shekhar Mukherjee Apr 20 '21 at 13:48
  • 1
    @SomShekharMukherjee: Yes, I would use a map or object for lookups if I found the original too slow. But without more understanding, I don't know if that should be written externally to the function to reuse across multiple calls to `combine`, or whether it could go inside `combine`. I'll look at yours. – Scott Sauyet Apr 20 '21 at 17:43
  • 1
    Added an updated version, and the Map actually ended up simplifying the code. – Scott Sauyet Apr 20 '21 at 18:40