简体   繁体   English

如何获取 JSON 数据的最小值、最大值和总和

[英]How to get the min, max, and sum of JSON data

I had JSON data that came back with single int values.我有 JSON 数据返回单个 int 值。 With some changes, the values are now coming back as arrays of ints (as well as the original format).经过一些更改,这些值现在返回为整数的 arrays(以及原始格式)。

{
  "value": 10,
  "value": 70,
  "value": 30,
  "value": 200
}

- and -

{
  "value": [64, 13, 55, 34, 52, 43, 59, 20, 20],
  "value": [10, 90, 20, 80, 30, 70, 60, 40, 50]
}

I had a formula that would return the min, max, and sum of the old version of JSON data.我有一个公式可以返回旧版本 JSON 数据的最小值、最大值和总和。 Now it doesn't work, and I can't figure out what would be the best way to re-write the function to handle the arrays.现在它不起作用,我不知道重写 function 以处理 arrays 的最佳方法是什么。 Or if its better to make a second function to handle just arrays and do a check if it is an int or array?或者,如果它更好地制作第二个 function 来处理 arrays 并检查它是 int 还是 array?

Is there a way that would return (from the numbers above):有没有一种方法可以返回(从上面的数字):

// no value array, apply to all
[ 10, 200, 310 ] // min, max, sum

- and -

// for each of the value arrays
[ 23, 64, 360 ] // val 1 - min, max, sum
[ 10, 90, 450 ] // val 2 - min, max, sum

 // input data const value = document.querySelectorAll( "div" ).forEach( el => { const contents = el.textContent, // get the text in the <div> json = JSON.parse( contents ), // parse the data jsonData = json.data; // get the data only // normalise the data // @from: https://stackoverflow.com/a/67294607/1086990 const normaliseData = arr => { const data = arr.map(({ value }) => value); return typeof arr[0].value === 'number'? [data]: data; }; // add into const const valueArray = normaliseData( jsonData ); // get the min / max / sum const minMaxSum = valueArray.forEach( e => { return [ Math.min(...e), Math.max(...e), [...e].reduce((v, w) => v + w) ]; }); // output console.log( minMaxSum ); });
 <div> { "data": [ { "value": [64, 23, 45, 34, 52, 43, 59, 40] }, { "value": [10, 90, 20, 80, 30, 70, 60, 40, 50] } ] } </div> <div> { "data": [ { "value": 600 }, { "value": 70 }, { "value": 30 } ] } </div>

Normalize the data by testing the type of the value of the first object in each array:通过测试每个数组中第一个 object 的值的类型来规范化数据:

const valueInArray = [{ value: [64, 23] }, { value: [45, 34] }];
const valueAsSingle = [{ value: 600 }, { value: 70 }];

const normalizeData = arr => {
  const data = arr.map(({ value }) => value);

  return typeof arr[0].value === 'number'
    ? [data]
    : data;
};

console.log(normalizeData(valueInArray));
//=> [ [ 64, 23 ], [ 45, 34 ] ]

console.log(normalizeData(valueAsSingle));
//=> [ [ 600, 70 ] ]

Now they are the same shape, and so you can treat them equally.现在它们是相同的形状,因此您可以平等对待它们。

You can use Math.max and Math.min to find the maximum and minimum of the array then assign the values in the specific variables.您可以使用 Math.max 和 Math.min 找到数组的最大值和最小值,然后分配特定变量中的值。

Currently, when you are using val.value it is consisting of the whole array and hence you also need to iterate over the array to find the max, min, or sum.目前,当您使用val.value时,它由整个数组组成,因此您还需要遍历数组以找到最大值、最小值或总和。

To find the sum use reduce on the val.value array and then add it in the acc[2] .要找到总和,请在 val.value 数组上使用reduce ,然后将其添加到acc[2]中。

 // input data const valueInArray = document.getElementById("valueInArray").innerHTML, valueAsSingle = document.getElementById("valueAsSingle").innerHTML; // parse const jsonArray = JSON.parse( valueInArray ), jsonNumber = JSON.parse( valueAsSingle ), jsonArrayData = jsonArray.data, jsonNumberData = jsonNumber.data; // get numbers const minMaxSumArray = jsonArrayData.reduce( ( acc, val ) => { // smallest number acc[0] = ( ( acc[0] === undefined || Math.min(...val.value) < acc[0] )? Math.min(...val.value): acc[0] ) // largest number acc[1] = ( ( acc[1] === undefined || Math.max(...val.value) > acc[1] )? Math.max(...val.value): acc[1] ) // sum of numbers acc[2] = ( acc[2] === undefined? val.value.reduce((v, w) => v + w): val.value.reduce((v, w) => v + w) + acc[2] ) console.log('answer', acc) // return the array return acc; }, [] );
 <div id="valueInArray"> { "data": [ { "value": [64, 23, 45, 34, 52, 43, 59, 40] }, { "value": [10, 90, 20, 80, 30, 70, 60, 40, 50] } ] } </div> <div id="valueAsSingle"> { "data": [ { "value": 10 }, { "value": 70 }, { "value": 30 } ] } </div>

My take on it: first, create a single Array of all values (either arrays or single) by concatening them and using Array.flat() to flatten it.我对此的看法:首先,通过连接它们并使用 Array.flat() 将其展平,创建一个包含所有值(arrays 或单个)的单个数组。 Then use a reducer to determine the sum and use Math.min/max for the min and max values.然后使用 reducer 确定总和并使用 Math.min/max 作为最小值和最大值。

 // input data const valuesInArray = JSON.parse( document.querySelector("#valueInArray").textContent).data; const singleValues = JSON.parse( document.querySelector("#valueAsSingle").textContent).data; // get all values from the objects to a single Array of values // (so: convert all to single values) const allValues = valuesInArray.map( v => v.value ).concat(singleValues.reduce( (acc, val) => [...acc, +val.value], [] ) ).flat(); // let's see what we have console.log(`All values from both objects: ${JSON.stringify(allValues)}`); // create sum, min and max const [ sum, min, max, ] = [ allValues.reduce( (a, v) => a + +v, 0), Math.min(...allValues), Math.max(...allValues) ]; console.log(`From all values sum is ${sum}, min ${min} and max ${max}`);
 div { display: none; }
 <div id="valueInArray"> { "data": [ { "value": [64, 23, 45, 34, 52, 43, 59, 40] }, { "value": [10, 90, 20, 80, 30, 70, 60, 40, 50] } ] } </div> <div id="valueAsSingle"> { "data": [ { "value": 10 }, { "value": 70 }, { "value": 30 } ] } </div>

The second snippet aggregates data per value, where the single values are added as a values array to valuesInArray .第二个片段聚合每个值的数据,其中单个值作为值数组添加到valuesInArray

 // input data const valuesInArray = JSON.parse( document.querySelector("#valueInArray").textContent).data; const singleValues = JSON.parse( document.querySelector("#valueAsSingle").textContent).data; // create sum, min and max *per value*, in one go const aggregatesAdded = valuesInArray.concat({ value: singleValues.reduce( (acc, val) => [...acc, +val.value], [] ) } ).reduce( (acc, val) => [...acc, {...val, aggregatedValues: { sum: val.value.reduce( (a, v) => a + +v, 0 ), min: Math.min(...val.value), max: Math.max(...val.value) } } ], []) document.querySelector("pre").textContent = JSON.stringify({data: aggregatesAdded}, null, 2);
 div { display: none; }
 <div id="valueInArray"> { "data": [ { "value": [64, 23, 45, 34, 52, 43, 59, 40] }, { "value": [10, 90, 20, 80, 30, 70, 60, 40, 50] } ] } </div> <div id="valueAsSingle"> { "data": [ { "value": 10 }, { "value": 70 }, { "value": 30 } ] } </div> <pre id="result"></pre>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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