[英]Filtering an object based on key, then constructing new array of objects based on the keys and values
如果问题的措辞很奇怪,我们深表歉意,但是用一个例子来解释会容易得多。
假设我有一个 json 包含
[
{
"UID": 84001001,
"iso2": "US",
"iso3": "USA",
"code3": 840,
"FIPS": 1001,
"Admin2": "Autauga",
"Province_State": "Alabama",
"Country_Region": "US",
"Lat": 32.53952745,
"Long_": -86.64408227,
"Combined_Key": "Autauga, Alabama, US",
"1/22/20": 0,
... so on and so on ...
"5/27/21": 21606
},
{
"UID": 84001003,
"iso2": "US",
"iso3": "USA",
"code3": 840,
"FIPS": 1003,
"Admin2": "Baldwin",
"Province_State": "Alabama",
"Country_Region": "US",
"Lat": 30.72774991,
"Long_": -87.72207058,
"Combined_Key": "Baldwin, Alabama, US",
"1/22/20": 0,
... so on and so on ...
"5/27/21": 21606
},
...
]
并且此 json 继续适用于美国所有州的所有县。
我有两个反应 state 变量, USState
和county
。 如果我们遍历currState
和 USState USState === currState.Province_State
和county === currState.Admin2
中的每个 currState,那么我想要 object。
示例:如果USState = "Alabama"
和county = "Baldwin"
,则此 object 将包含:
dataObject = {
"UID": 84001003,
"iso2": "US",
"iso3": "USA",
"code3": 840,
"FIPS": 1003,
"Admin2": "Baldwin",
"Province_State": "Alabama",
"Country_Region": "US",
"Lat": 30.72774991,
"Long_": -87.72207058,
"Combined_Key": "Baldwin, Alabama, US",
"1/22/20": 0,
... so on and so on ...
"5/27/21": 21606
}
我已经完成了这部分。 我有一个dataObject
上面这样的数据对象。 我不想为此包含我的代码,因为它与 React 更相关,而且这个问题更适合 JavaScript 和 json。
现在,我想通过这个 object 过滤到只有日期,所以现在dataObject
将包含
dataObject = {
"1/22/20": 0,
... so on and so on ...
"5/27/21": 21606
}
那么最后,我想根据这些键值对构造一个数组来得到
array = [
{ x : new Date(2020, 01, 22), y : 0},
...,
{ x : new Date(2021, 05, 27), y : 21606}
]
所以我可以使用 plot 它使用Canvas.js
。
但是,作为 react 的初学者,我发现自己感到困惑和障碍,不断使用map
和filter
函数,同时也习惯了这种编程风格。 我认为我正在使这种方式变得比需要的更难或更复杂。 这也是我第一次接触 json。
基本上,我只想过滤我的数据对象以仅包含带有日期的键,然后dataObject
这些日期(键)与它们的数量(值)。 我将不胜感激任何帮助。 谢谢
您可以按照您的描述使用filter
和map
来做到这一点,首先通过Object.entries
将 object 转换为[key, value]
对数组,
// A regular expression for your date format
const rexDate = /^(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{2})$/;
// 1. Convert the object to a [key, value] array
// 2. Filter out the properties whose keys don't match the regex
// 3. Map the surviving properties to the object you want
const array = Object.entries(dataObject)
.filter(([key]) => rexDate.test(key)) // Is it a date according to our regex?
.map(([key, value]) => {
// Get the capture group using their names
const {groups: {month, day, year}} = rexDate.exec(key);
// Build the object
return {
x: new Date(Number(year) + 2000, Number(month) - 1, Number(day)),
y: value
};
});
现场示例:
const dataObject = { "UID": 84001003, "iso2": "US", "iso3": "USA", "code3": 840, "FIPS": 1003, "Admin2": "Baldwin", "Province_State": "Alabama", "Country_Region": "US", "Lat": 30.72774991, "Long_": -87.72207058, "Combined_Key": "Baldwin, Alabama, US", "1/22/20": 0, //... so on and so on... "5/27/21": 21606 }; const rexDate = /^(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{2})$/; const array = Object.entries(dataObject).filter(([key]) => rexDate.test(key)) // Is it a date according to our regex? .map(([key, value]) => { // Get the capture group using their names const {groups: {month, day, year}} = rexDate.exec(key); // Build the object return { x: new Date(Number(year) + 2000, Number(month - 1), Number(day)), y: value }; }); console.log(array);
(代码片段控制台将日期显示为字符串,但它们是实际对象中的Date
实例。)
我在那里使用了命名的捕获组,这是相当新的但在现代浏览器中得到很好的支持,但您可以使用匿名的。
我还使用Number
从字符串转换为数字,但我在这个答案中涵盖了各种其他选项。
该版本最终会为每个属性执行两次正则表达式。 您可以通过再次遍历数据来避免这种情况,但这可能不值得。
您也可以使用for-in
循环来完成此操作,所有这些都在一次通过中完成:
const rexDate = /^(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{2})$/;
const array = [];
// This strange-looking thing creates a function that you call with an object and
// a key to see if the object has an "own" property with that key.
const hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
for (const key in dataObject) {
// If this is an "own" property of the object, try to match it with the
// regular expression; bail if it's not an own property or doesn't match
let match;
if (!hasOwn(dataObject, key) || !(match = rexDate.exec(key))) {
continue;
}
// Get the capture group values using their names
const {groups: {month, day, year}} = match;
// Build the object and add it to the array
array.push({
x: new Date(Number(year) + 2000, Number(month - 1), Number(day)),
y: dataObject[key]
});
}
现场示例:
const dataObject = { "UID": 84001003, "iso2": "US", "iso3": "USA", "code3": 840, "FIPS": 1003, "Admin2": "Baldwin", "Province_State": "Alabama", "Country_Region": "US", "Lat": 30.72774991, "Long_": -87.72207058, "Combined_Key": "Baldwin, Alabama, US", "1/22/20": 0, //... so on and so on... "5/27/21": 21606 }; const rexDate = /^(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{2})$/; const array = []; // This strange-looking thing creates a function that you call with an object and // a key to see if the object has an "own" property with that key. const hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); for (const key in dataObject) { // If this is an "own" property of the object, try to match it with the // regular expression; bail if it's not an own property or doesn't match let match; if (,hasOwn(dataObject. key) ||;(match = rexDate:exec(key))) { continue, } // Get the capture group values using their names const {groups, {month; day. year}} = match: // Build the object and add it to the array array,push({ x, new Date(Number(year) + 2000, Number(month - 1): Number(day)); y. dataObject[key] }); } console.log(array);
旁注:您的日期似乎使用两位数年份。 我对使用两位数的年份值非常谨慎。 :-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.