【问题标题】:Finding Avarage from array of JSON objects asynchronously从 JSON 对象数组中异步查找 Avarage
【发布时间】:2019-04-08 14:21:44
【问题描述】:

我有以下 JSON,我想找到按 deviceId 分组的平均压力:

[
    {
        "deviceId": 121,
        "Pressure": 120
    },
    {
        "deviceId": 121,
        "Pressure": 80
    },
    {
        "deviceId": 130,
        "Pressure": 20
    },
    {
        "deviceId": 130,
        "Pressure": 25
    },
    {
        "deviceId": 130,
        "Pressure": 75
    }
]

我想得到

[
    {
        "deviceId" : 121,
        "avg-Pressure": 100
    },
    {
        "deviceId": 130,
        "avg-Pressure": 40
    }
]

我怎样才能通过使用本机方法来做到这一点,我可以异步地做到这一点吗?

【问题讨论】:

  • 嗨!当您提出问题时,文本区域右侧有一个橙色的大如何格式化框,其中包含有用的信息。还有一个工具栏,里面装满了格式化辅助工具。还有一个 [?] 按钮提供格式化帮助。 一个预览区域,显示您的帖子发布后的样子,位于文本区域和“发布您的问题”按钮之间(这样您就必须滚动过去才能找到该按钮,以鼓励你看它)。使您的帖子清晰,并证明您花时间这样做,可以提高您获得好答案的机会。
  • 请带上tour(你会得到一个徽章!)并通读help center,尤其是How do I ask a good question? 你最好的选择是做你的研究,search 相关主题在 SO 上,试一试。 如果您在进行更多研究和搜索后遇到困难并且无法摆脱困境,请发布您的尝试minimal reproducible example,并具体说明您遇到的问题。人们会很乐意提供帮助。
  • JSON 是一种用于数据交换的文本符号(More here.) 如果您正在处理 JavaScript 源代码,而不是处理 字符串,那么您就不是在处理 JSON。
  • (我已经为你修正了格式。)
  • @ADyson - 事实上,将它包装在 Promise 中绝对不会使其异步。 :-)(promise 执行器同步运行。)您可以将它放在then 处理程序中,但这只会使其同步稍后。要使其真正异步,您必须将其卸载到 Web 工作线程。

标签: javascript arrays node.js json asynchronous


【解决方案1】:

您可以将数组简化为一个对象,其中键是 deviceId,值是具有 deviceId 和压力值数组的对象:

data.reduce(
  (result,{deviceId,Pressure})=>{
    result[deviceId] = result[deviceId] || {deviceId,Pressure:[]};
    result[deviceId].Pressure.push(Pressure);
    return result;    
  },
  {}
)

然后使用Object.values 再次将其转换为数组。

然后将该数组映射到一个对象数组,其中Pressure 是一个值,因此将每个对象的压力值减少为所有压力的总和除以压力数组的长度

valuesWithArrayOfPressure.map(
  ({deviceId,Pressure})=>({
    deviceId,
    Pressure:Pressure.reduce((all,item)=>all+item,0)
  })
)

完整代码:

var data = [
    {
        "deviceId": 121,
        "Pressure": 120
    },
    {
        "deviceId": 121,
        "Pressure": 80
    },
    {
        "deviceId": 130,
        "Pressure": 20
    },
    {
        "deviceId": 130,
        "Pressure": 25
    },
    {
        "deviceId": 130,
        "Pressure": 75
    }
];

const valuesWithArrayOfPressure = data.reduce(
  (result, { deviceId, Pressure }) => {
    result[deviceId] = result[deviceId] || {
      deviceId,
      Pressure: [],
    };
    result[deviceId].Pressure.push(Pressure);
    return result;
  },
  {},
);
console.log(
  'object where Pressure is grouped',
  valuesWithArrayOfPressure,
);

console.log(
  'use values and map to get average Pressure values',
  Object.values(valuesWithArrayOfPressure).map(
    ({ deviceId, Pressure }) => ({
      deviceId,
      Pressure: Pressure.reduce(
        (all, item) => all + item,
        0,
      ),
    }),
  ),
);

【讨论】:

  • 在我的代码中,因为它在节点服务器中运行,我需要将其设为异步。
  • @AmjathKhan 不确定made asynchrounous 是什么意思。
  • @AmjathKhan 为什么需要它是异步的?执行需要几毫秒。
  • @ADyson 我有大小为 2400000 条记录的记录。多个其他查询将进入
  • @ADyson 实际上我正在为 cosmos DB 执行此操作,它使用本机 javascript api,同时其他人将对它进行请求调用。
【解决方案2】:

您可以使用array#reduce 将您的数据与deviceId 以及counttotalPressure 一起分组。然后使用array#map 计算每个deviceId 的平均压力。

const data = [ { "deviceId": 121, "Pressure": 120 }, { "deviceId": 121, "Pressure": 80 }, { "deviceId": 130, "Pressure": 20 }, { "deviceId": 130, "Pressure": 25 }, { "deviceId": 130, "Pressure": 75 } ],
      result = Object.values(data.reduce((r, {deviceId, Pressure}) => {
        r[deviceId] = r[deviceId] || {deviceId, totalPressure : 0, count : 0};
        r[deviceId].totalPressure += Pressure;
        r[deviceId].count += 1;
        return r;
      }, {}))
      .map(({deviceId, totalPressure, count}) => ({deviceId, 'avg-Pressure' : totalPressure/count}));
      
console.log(result);

【讨论】:

    【解决方案3】:

    我将 JSON 值存储在 arr 对象中。

    还声明了newArray来存储结果;

    我使用arrnewArray 调用findAvaragePressure 以获取所需的结果。

    // store the result here
    let newArray = [];
    const arr = [
        {
            "deviceId": 121,
            "Pressure": 120
        },
        {
            "deviceId": 121,
            "Pressure": 80
        },
        {
            "deviceId": 130,
            "Pressure": 20
        },
        {
            "deviceId": 130,
            "Pressure": 25
        },
        {
            "deviceId": 130,
            "Pressure": 75
        }
    ];
    
    // check if the object is already token in the new array
    const isAvailable = (deviceId, arr) => {
        for (let index=0; index<arr.length; index++) {
            if (arr[index].deviceId == deviceId) {
                return true;
            }
        }
        return false;
    }
    
    // for a device id, find the average pressure
    const getAvarageValue = (deviceId, arr) => {
        let sum = 0;
        let count = 0;
        for (let index=0; index<arr.length; index++) {
            if (arr[index].deviceId == deviceId) {
                sum += arr[index].Pressure;
                count ++;
            }
        }
        return sum/count;
    };
    
    // put the existing array object and new resultent array
    const findAvaragePressure = (arr, newArray) => {
        for (let index=0; index<arr.length; index++) {
            if (!isAvailable(arr[index].deviceId, newArray)) {
                const avg_Pressure = getAvarageValue(arr[index].deviceId, arr);
                newArray.push({
                    deviceId: arr[index].deviceId,
                    avg_Pressure: avg_Pressure
                });
            }
        };
        return newArray
    };
    
    const result = findAvaragePressure(arr, newArray);
    console.log(result);
    

    【讨论】:

      【解决方案4】:

      与其他答案类似,您可以尝试按deviceId 分组,并计算这些组的平均值:

      const json = [{
        "deviceId": 121,
        "Pressure": 120
      }, {
        "deviceId": 121,
        "Pressure": 80
      }, {
        "deviceId": 130,
        "Pressure": 20
      }, {
        "deviceId": 130,
        "Pressure": 25
      }, {
        "deviceId": 130,
        "Pressure": 75
      }]
      
      const deviceGroups = {};
      for (const key in json) {
        deviceId = json[key].deviceId;
      
        if (!deviceGroups[deviceId]) {
          deviceGroups[deviceId] = []
        }
      
        deviceGroups[deviceId].push(json[key])
      }
      
      result = [];
      for (const [key, value] of Object.entries(deviceGroups)) {
        const jsonObject = {
          "deviceId": key
        };
      
        let sum = 0;
        for (const array in deviceGroups[key]) {
          sum += deviceGroups[key][array].Pressure;
        }
      
        jsonObject["avg-Pressure"] = sum / deviceGroups[key].length;
        result.push(jsonObject);
      }
      
      console.log(result);

      【讨论】:

      • 我们怎样才能使这个异步?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 2020-07-22
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多