0

I need some help with this algorithm, i would like to get the sorted highest prices of Venta (sell), i can sort each pair content, but i can't realize how to sort the properties order too (by the highest price of first inner). Below is the code i have for now, and my expected output. Thanks in advance.

const data = {
    busd_ars: {
        belo: 'Invalid pair',
        binanceP2P: { Compra: 280, Venta: 278.41 },
        bitso: { Compra: 283.6615, Venta: 279.4225 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 281.4251, Venta: 267.8393 }
    },
    dai_ars: {
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: { Compra: 281.45, Venta: 278.65 },
        bitso: { Compra: 287.5624, Venta: 276.7951 },
        buenbit: { Compra: 285.8, Venta: 274.8 },
        cryptoMkt: { Compra: 279.6464, Venta: 267.7461 }
    },
    usdc_ars: {
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: 'Invalid pair',
        bitso: { Compra: 283.6615, Venta: 279.4205 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 279.5047, Venta: 267.8935 }
    },
    usdt_ars: {
        belo: { Compra: 282, Venta: 270 },
        binanceP2P: { Compra: 280.49, Venta: 279.15 },
        bitso: { Compra: 287.1397, Venta: 276.4963 },
        buenbit: { Compra: 285.2, Venta: 275.6 },
        cryptoMkt: { Compra: 279.4978, Venta: 268.0277 }
    }
}


const getHighPrices = (stablesFiat) => {
    const result = {}
    for (let pair in stablesFiat) {
        let data = {}
        Object.entries(stablesFiat[pair])
            .filter(x => x[1] != 'Invalid pair')
            .sort((a, b) => b[1].Venta - a[1].Venta)
            .slice(0, 3)
            .forEach(x => {
                data[x[0]] = x[1].Venta
            })
        result[pair] = data
    }
    return result
}

console.log(getHighPrices(data))


// expected output

const result = {
    busd_ars: {},
    usdc_ars: {},
    usdt_ars: {},
    dai_ars: {}
}
sonEtLumiere
  • 4,461
  • 3
  • 8
  • 35
  • What's the expected output again? Could you provide an example of how this data will look like once it's sorted? I see the output there is showing the structure but cannot say which is the inner values of those entries sorted by. – Rigoberto Ramirez Cruz Aug 04 '22 at 04:14
  • @RigobertoRamirezCruz click Run code snippet to see the inner values of those objects, check out the first value of each object, the order of highest to lower is: busd_ars, usdc_ars, usdt_ars, dai_ars – sonEtLumiere Aug 04 '22 at 04:17
  • And the result will be what, an object of objects? Wouldn't you need the value of the highest for each pair? I suggest you use an array instead where index 0 will be highest and 1 second highest, and so on and so forth; instead of an object. – Rigoberto Ramirez Cruz Aug 04 '22 at 04:29
  • @RigobertoRamirezCruz exactly, i need as result an object of objects – sonEtLumiere Aug 04 '22 at 04:30

2 Answers2

2

You cannot sort a JavaScript object in an order.

In this thread (Does JS guarantee object property order), you can see examples and excerpts from the documentation which says so.

If you want to order data, you should not have it be an object, but instead an array.

For example:

const data = [
    {
        name: 'busd_ars',
        belo: 'Invalid pair',
        binanceP2P: { Compra: 280, Venta: 278.41 },
        bitso: { Compra: 283.6615, Venta: 279.4225 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 281.4251, Venta: 267.8393 }
    },
    {
        name: 'dai_ars',
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: { Compra: 281.45, Venta: 278.65 },
        bitso: { Compra: 287.5624, Venta: 276.7951 },
        buenbit: { Compra: 285.8, Venta: 274.8 },
        cryptoMkt: { Compra: 279.6464, Venta: 267.7461 }
    },
    {
        name: 'usdc_ars',
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: 'Invalid pair',
        bitso: { Compra: 283.6615, Venta: 279.4205 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 279.5047, Venta: 267.8935 }
    },
    {
        name: 'usdt_ars',
        belo: { Compra: 282, Venta: 270 },
        binanceP2P: { Compra: 280.49, Venta: 279.15 },
        bitso: { Compra: 287.1397, Venta: 276.4963 },
        buenbit: { Compra: 285.2, Venta: 275.6 },
        cryptoMkt: { Compra: 279.4978, Venta: 268.0277 }
    }
]

Then you can sort this array by a certain property like:

data.sort((a, b) => a.belo.Venta > b.belo.Venta) //just an example

Even if you do this and convert it back to an Object, there is no guarantee that it will stay in order.

cSharp
  • 2,884
  • 1
  • 6
  • 23
0

You could use the following function (sortByHighestChildVentaValue) to sort the dataset. It creates an array from the initial object with a projection where each entry have the pair and highest Venta value for the markets where that pair is sold. Then, the array is sorted in descending order by the highest value and finally transform to an object.

That last step is discourage due to, as pointed out by @cSharp in the other answer, this structure does not guaranty the order.

const data = {
    busd_ars: {
        belo: 'Invalid pair',
        binanceP2P: { Compra: 280, Venta: 278.41 },
        bitso: { Compra: 283.6615, Venta: 279.4225 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 281.4251, Venta: 267.8393 }
    },
    dai_ars: {
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: { Compra: 281.45, Venta: 278.65 },
        bitso: { Compra: 287.5624, Venta: 276.7951 },
        buenbit: { Compra: 285.8, Venta: 274.8 },
        cryptoMkt: { Compra: 279.6464, Venta: 267.7461 }
    },
    usdc_ars: {
        belo: { Compra: 282.0846, Venta: 269.784 },
        binanceP2P: 'Invalid pair',
        bitso: { Compra: 283.6615, Venta: 279.4205 },
        buenbit: { Compra: 285.2, Venta: 275.5 },
        cryptoMkt: { Compra: 279.5047, Venta: 267.8935 }
    },
    usdt_ars: {
        belo: { Compra: 282, Venta: 270 },
        binanceP2P: { Compra: 280.49, Venta: 279.15 },
        bitso: { Compra: 287.1397, Venta: 276.4963 },
        buenbit: { Compra: 285.2, Venta: 275.6 },
        cryptoMkt: { Compra: 279.4978, Venta: 268.0277 }
    }
}

const sortByHighestChildVentaValue = pairs => Object.keys(pairs)
  // Convert this to array for a better manipulation
  .map(p => {
    // Get the market where the pair have the max value for Venta
    const highestPerMarket = Object.keys(pairs[p])
      .map(market => ({ market: market, venta: pairs[p][market].Venta }))
      .filter(market => !!market.venta)
      .sort((a,b) => b.venta - a.venta)[0]
    
    // return as an object with the pair name, e.g. usdt_ars and the
    // max Venta value found.
    return { pair: p, highest: highestPerMarket.venta }
  })
  // Sort by highest Venta value amongst the different pairs
  .sort((a,b) => b.highest - a.highest)
  // This is to return an object instead of an array. Discourage to use
  // it as an object but required by question.
  .reduce((acc, curr) => {
    acc[curr.pair] = {}
    return acc
  }, {})

console.log(sortByHighestChildVentaValue(data))

// expected output

const result = {
    busd_ars: {},
    usdc_ars: {},
    usdt_ars: {},
    dai_ars: {}
}