简体   繁体   中英

How can I sort through an Axios response?

I am using Axios to execute a GET request to a public API, I need to combine the names if they are the same and add the values up to only show the top 20 (It's a large dataset) based on the highest to lowest amounts(ascending order).

Axios Response

 [
    {
        name: "foo1",
        value: "8123.30"
    }, 
    
    {
        name: "foo1",
        value: "2852.13"
        
    }, 
    
    {
        name: "foo2",
        value: "5132.23"
    },
   
    {
        name: "foo1",
        value: "1224.20"
       
    }, 

     {
        name: "foo2",
        value: "1285.23"
        
    }
   1200...
];

Expected Output

[
  {   name: "foo1",
      value: "12199.63" // from all combined "foo1" amounts in the dataset
  },

  {
     name: "foo2",
     value: "6417.46"  // from all combined "foo2" amounts in the dataset
  },
    18..
]

I tried to do something like this....

const fetchData = () => {
    return axios.get(url)
    .then((response) => response.data)
};

function onlyWhatINeed() {
  const newArr = []
  return fetchData().then(data => {
    const sortedData = data.sort((a, b) => parseFloat(a.value) - parseFloat(b.value)); 
    // I need to loop through the dataset and add all the "values" up
   // returning only the top 20 highest values in an array of those objects 
    newArr.push(sortedData)
  })
}

But I am confused as to how to push this data to a new array of the sorted data (top 20 values in ascending order) and use this data in my web application. I am a bit new to creating REST APIs so if you could provide articles and/or resources so I can understand a little more that would be an awesome bonus!

You can combine the entries that share the same name using a map, then sort the map and keep the first twenty elements :

function onlyWhatINeed() {
  const newArr = []
  return fetchData().then(data => {
    let map = new Map();
    data.forEach(d => {
      if(!map.has(d.name)) {
        map.set(d.name, parseFloat(d.value));
      } else {
        map.set(d.name, map.get(d.name) + parseFloat(d.value));
      }
    })
  
    return Array.from(map.entries()).sort((a, b) => a.value - b.value).slice(0, 20);

  })
}

Since you're dealing with a large dataset, I recommend that you handle this server side instead of offloading the sorting to your clients.

async function fetchData(){
    const { data } = await axios.get(url);
    let newArr = []
    data.forEach((e,i) => {
        let index = newArr.findIndex(el => el.name === e.name);
        if(index !== -1 ) newArr[index].value += parseFloat(e.value); //add to the value if an element is not unique
        if(index === -1 ) newArr.push({...e, value: parseFloat(e.value)}); //push to the array if the element is unique and convert value to float
    });
    return newArr.sort((a,b) => a.value - b.value).slice(0,20);//returns an array of 20 elements after sorting
}

Please do more research on how to work with arrays and objects in general.

If you happen to already be using lodash , then here's a functional-style solution using lodash chaining. Probably not optimal performance, but could be useful for relatively small datasets.

const _ = require('lodash');

const data =  [
  {
    name: "foo1",
    value: "8123.30"
  },
  {
    name: "foo1",
    value: "2852.13"
  },
  {
    name: "foo2",
    value: "5132.23"
  },
  {
    name: "foo1",
    value: "1224.20"
  },
  {
    name: "foo2",
    value: "1285.23"
  },
  {
    name: "foo3",
    value: "1000.00"
  },
  {
    name: "foo3",
    value: "2000.00"
  }
];
 
// 1. convert string values to floats
// 2. group by name
// 3. sum values by name
// 4. sort by descending value
// 5. take top 20
const output =
  _(data)
    .map(obj => ({
      name: obj.name,
      value: parseFloat(obj.value)
    }))
    .groupBy('name')
    .map((objs, key) => ({
      name: key,
      value: _.sumBy(objs, 'value')
    }))
    .orderBy(['value'], 'desc')
    .slice(0, 20)
    .value();

console.log('output:', output);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM