#javascript #node.js #sorting #data-structures #axios
#javascript #node.js #сортировка #структуры данных #axios
Вопрос:
Я использую Axios для выполнения запроса GET к общедоступному API, мне нужно объединить имена, если они совпадают, и добавить значения, чтобы отображать только верхние 20 (это большой набор данных) на основе от самых высоких до самых низких значений (в порядке возрастания).
Ответ Axios
[
{
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...
];
Ожидаемый результат
[
{ 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..
]
Я пытался сделать что-то подобное….
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)
})
}
Но я не понимаю, как перенести эти данные в новый массив отсортированных данных (20 лучших значений в порядке возрастания) и использовать эти данные в моем веб-приложении. Я немного новичок в создании REST API, поэтому, если бы вы могли предоставить статьи и / или ресурсы, чтобы я мог понять немного больше, это было бы потрясающим бонусом!
Комментарии:
1. Насколько велик этот набор данных (сколько записей)?
2. Axios возвращает 1220 объектов
Ответ №1:
Вы можете объединить записи с одинаковыми именами, используя карту, затем отсортировать карту и сохранить первые двадцать элементов :
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);
})
}
Поскольку вы имеете дело с большим набором данных, я рекомендую вам обрабатывать эту серверную часть вместо того, чтобы перегружать сортировку своим клиентам.
Ответ №2:
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
}
Пожалуйста, проведите дополнительные исследования о том, как работать с массивами и объектами в целом.
Ответ №3:
Если вы уже используете Lodash, то вот решение в функциональном стиле, использующее цепочку lodash. Вероятно, не оптимальная производительность, но может быть полезно для относительно небольших наборов данных.
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);