如果名称和日期匹配两个 API JSON 数据,如何求和? [英] How to sum if name and date match two API JSON data?

查看:20
本文介绍了如果名称和日期匹配两个 API JSON 数据,如何求和?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个 API Request/URL

这是第一个 API 请求 URL 和数据来自

 http://127.0.0.1:8000/api/onlineUserData{在线用户数据":[[月",阿曼尼亚", Shyral", 多潘"],[11 月 16 日", 9 , 11 , 6 ] ,[11 月 18 日", 5 , 0 , 0 ]]};

这是第二个 API 请求 URL 和数据来自

 http://127.0.0.1:8000/api/offlineUserData{离线用户数据":[[月",阿曼尼亚", Shyral", Diskhant"],[11 月 16 日", 4 , 7 , 0 ],[11 月 20 日", 12 , 8 , 9 ],]};

现在我想对两个 JSON 数据求和,如果它们的用户名和月份/日期在两个 API 数据之间匹配

 {所有用户":[["月",阿曼尼亚", Shyral"、多尔潘"、迪坎特"],["11 月 16 日", 13 , 18 , 6 , 0 ],["11 月 18 日, 5 , 0 , 0 , 0 ],["11 月 20 日, 12 , 8 , 0 , 9 ], ]]

解决方案

组合这两个集合的最大障碍是将值放置在嵌套数组中.这意味着他们所处的位置是价值含义的唯一指标.

因此需要将数据转换为具有键和值的结构.这为每个值提供了名称和含义,并且还使组合它们更不容易出错.

<预><代码>[{'Month': 'Nov-16','阿曼尼亚':9,'Shyral': 11,多潘":6},{...},...];

现在您需要确保所有的键都匹配,这样当您开始计数时,您可以使用相同的数据集进行计数.

请注意,Diskhant 已添加到下面的对象中.现在这个名字存在于每个对象中,并且可以计算出他的总数.

<预><代码>[{'Month': 'Nov-16','阿曼尼亚':9,'Shyral': 11,'多潘':6,'Diskhant':0},{...},...];

从这里您可以将两组合并为一组,并开始过滤重复的 Month 值.当发生这样的重复时,将当前对象的值添加到并返回结果.

我确实相信这可以变得更简单,但我的尝试让我制作了所有这些辅助函数以确保正确操作数据.如果您需要组合它们,它还允许您输入 2 个以上的数据集.

const online = {在线用户数据":[[月",Amania",Shyral",Dorpan"],[11 月 16 日", 9, 11, 6],[11 月 18 日", 5, 0, 0]]};const 离线 = {离线用户数据":[[月",Amania",Shyral",Diskhant"],[11 月 16 日", 4, 7, 0],["Nov-20", 12, 8, 9],]};/*** 将嵌套数组转换为对象数组.*/const tableToObjects = 数据 =>{const [ 标题,...条目] = 数据;return entry.map(entry => entry.reduce((acc, cur, i) => {acc[headers[i]] = cur;返回acc;}, {}));};/*** 将对象数组转换为嵌套数组.*/const objectsToTable = 数据 =>[Object.keys(data[0]),...(data.map(entry => Object.values(entry)))];/*** 返回所有存在的键的数组.*/const getKeyMap = 数据 =>[...data.reduce((set, entry) => {Object.keys(entry).forEach(key => set.add(key));返回集;}, new Set())];/*** 修改数据以确保所有对象都具有* 相同的键.这是获得正确输出所必需的* 计算和累加每个对象的值时.*/const equalizeData = 数据 =>{const 键 = getKeyMap(data);return data.map(entry => keys.reduce((obj, key) => {obj[key] = entry[key] ||0返回对象;}, {}));}/*** 按 Month 属性合并数据.* 如果数组中已经存在月份,则值* 该对象将被添加到现有对象中.*/const mergeData = 数据 =>data.reduce((arr, entry) => {const { Month, ...rest } = entry;const present = arr.find(newEntry => newEntry['Month'] === Month);如果(存在){Object.entries(rest).forEach(([ key, value ]) => {present[key] = (present[key] || 0) + 值;});} 别的 {arr.push(条目);}返回 arr;}, []);/*** 使用以上所有函数组合的函数* 将两个嵌套数组合并为一个嵌套数组.* 返回具有单个 `allUsers` 属性的对象.*/const allUsers = (...dataSets) =>{const allData = dataSets.flatMap(dataSet => {const table = Object.values(dataSet)[0];返回 tableToObjects(table);});const equalizedData = equalizeData(allData)const mergeData = mergeData(equalizedData);返回 {'allUsers': objectsToTable(mergedData)};};//调用函数.const 结果 = allUsers(online, offline);//这只是为了查看函数的输出.const output = document.getElementById('output');output.innerHTML = JSON.stringify(result, null, 2);

pre {显示:内联块;背景色:#f7f7f7;边框:1px 实心 #d0d0d0;边框半径:5px;填充:15px;}

<code><pre id="output"></pre></code>

There are two API Request/ URL

This is first API Request URL and data coming from

     http://127.0.0.1:8000/api/onlineUserData

                   {"onlineUserData":[
                      ["Month"  , "Amania"   , "Shyral" , "Dorpan"],
                      ["Nov-16" ,    9       ,   11     ,    6    ] ,
                      ["Nov-18" ,    5       ,   0      ,    0    ]
                    ]};

This is second API Request URL and data coming from

     http://127.0.0.1:8000/api/offlineUserData

                   {"offlineUserData":[
                      ["Month"  , "Amania" , "Shyral" , "Diskhant"],
                      ["Nov-16" ,    4     ,    7     ,     0     ], 
                      ["Nov-20" ,    12    ,    8     ,     9     ], 
                    ]};

Now i want to sum two JSON data if their name of user and month/date match between two API data

  {"AllUser":[
      [" Month"   , "Amania" , "Shyral" , "Dorpan","Diskhant" ],
      [" Nov-16"  ,  13      ,   18     ,    6    ,    0      ], 
      [" Nov-18 " ,  5       ,    0     ,    0    ,    0       ],
      [" Nov-20 " ,  12      ,    8     ,    0    ,    9      ],           ]
   ] 

解决方案

The biggest hurdle in combining these two sets is that the values are placed inside of nested arrays. This means that the position that they're in is the only indicator of what the value means.

Therefor the data needs to be converted into a structure with keys and values. This gives each value a name and meaning of what it is and also makes combining them less prone to errors.

[
  {
    'Month': 'Nov-16',
    'Amania': 9,
    'Shyral': 11,
    'Dorpan': 6
  },
  {
    ...
  },
  ...
];

Now you need to make sure that all your keys match up, so that when you start counting you have equal sets of data to count with.

Notice that Diskhant has been added to the object below. Now that name exists in every object and a total of his count can be calculated.

[
  {
    'Month': 'Nov-16',
    'Amania': 9,
    'Shyral': 11,
    'Dorpan': 6,
    'Diskhant': 0
  },
  {
    ...
  },
  ...
];

From here you can combine the two sets into one and start filtering for duplicate Month values. When such a duplicate occurs add the value of the current object to and return the result.

I do believe this can be made simpler, but my attempt left me making all of these helper functions to make sure that the data is manipulated correctly. It also enables you to enter more than 2 datasets if you need to combine them.

const online = {
  "onlineUserData": [
    ["Month", "Amania", "Shyral", "Dorpan"],
    ["Nov-16", 9, 11, 6],
    ["Nov-18", 5, 0, 0]
  ]
};

const offline = {
  "offlineUserData": [
    ["Month", "Amania", "Shyral", "Diskhant"],
    ["Nov-16", 4, 7, 0],
    ["Nov-20", 12, 8, 9],
  ]
};

/**
 * Converts the nested arrays to an array of objects.
 */
const tableToObjects = data => {
  const [ headers, ...entries ] = data;
  return entries.map(entry => entry.reduce((acc, cur, i) => {
    acc[headers[i]] = cur;
    return acc;
  }, {}));
};

/**
 * Converts an array of objects into nested arrays.
 */
const objectsToTable = data => [
  Object.keys(data[0]),
  ...(data.map(entry => Object.values(entry)))
];

/**
 * Returns an array of all keys that are present.
 */
const getKeyMap = data => [...data.reduce((set, entry) => {
  Object.keys(entry).forEach(key => set.add(key));
  return set;
}, new Set())];

/**
 * Modifies the data to ensure that all objects have the
 * same keys. This is necessary to get a correct output
 * when counting and adding up the values of each object.
 */
const equalizeData = data => {
  const keys = getKeyMap(data);
  return data.map(entry => keys.reduce((obj, key) => {
    obj[key] = entry[key] || 0
    return obj;
  }, {}));
}

/**
 * Merges the data by the Month property.
 * If a Month is already present in the array then the values
 * of that object will be added to the existing object.
 */
const mergeData = data => data.reduce((arr, entry) => {
  const { Month, ...rest } = entry;
  const present = arr.find(newEntry => newEntry['Month'] === Month);
  if (present) {
    Object.entries(rest).forEach(([ key, value ]) => {
      present[key] = (present[key] || 0) + value;
    });
  } else {
    arr.push(entry);
  }
  return arr;
}, []);

/**
 * Function that uses all the functions from above to combine
 * the two nested arrays into a single nested array.
 * Returns an object with a single `allUsers` property.
 */
const allUsers = (...dataSets) => {
  const allData = dataSets.flatMap(dataSet => {
    const table = Object.values(dataSet)[0];
    return tableToObjects(table);
  });
  const equalizedData = equalizeData(allData)
  const mergedData = mergeData(equalizedData);
  return {
    'allUsers': objectsToTable(mergedData)
  };
};

// Call the function.
const result = allUsers(online, offline);

// This is just to see the output of the function.
const output = document.getElementById('output');
output.innerHTML = JSON.stringify(result, null, 2);

pre {
  display: inline-block;
  background-color: #f7f7f7;
  border: 1px solid #d0d0d0;
  border-radius: 5px;
  padding: 15px;
}

<code><pre id="output"></pre></code>

这篇关于如果名称和日期匹配两个 API JSON 数据,如何求和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆