处理对象数组中的某些属性
Process certain properties in array of objects
我正在尝试处理对象数组中的一些属性。
顺序总是一样的,因为在第二个 属性 之后总是接下来的 12 个条目的日期范围,之后的所有内容都被排除在外,有时可以是两个,就像在这个例子中或者可能更多。
所以我想做的是排除除关键字和日期范围之外的所有内容。
const data = [{
"keyword": "foo",
// This key never changes
"search_vol": 0,
// These keys can change when they start, i.e. starts jan-21
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
// These would change to different properties in name and amount
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"drain": "TRUE",
"toilet": "TRUE"
}]
我想这样做,以便稍后我可以获得每个对象日期的最大值,并有一个条目包含达到该最大值的月份
预期最终输出:
const data = [{
"keyword": "foo",
"search_vol": 0,
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
"Max months": ['apr-21'],
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"Max months": ['jan-21','mar-21'],
"drain": "TRUE",
"toilet": "TRUE"
}]
是否值得将流程分开,先搁置日期,然后获取最大值,还是最好一次完成所有流程?
这是我的尝试,不包括与数据的合并,但我认为过于复杂
const data = [{
"keyword": "foo",
"search_vol": 0,
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"drain": "TRUE",
"toilet": "TRUE"
}]
const headers = Object.keys(data[0]).filter((_, index) => index === 0 || ( index >= 1 && index <= 13))
const dates = data.reduce((acc, obj) => {
const filtered = headers.reduce((entries, key) => ({ ...entries, [key]: obj[key] }), {})
acc.push(filtered)
return acc
}, [])
const months = dates.map(({ keyword, ...dates }) => {
const max = Math.max(...Object.values(dates))
const maxMonths = Object.entries(dates).reduce((acc, [key, value]) => {
if (value === max) acc.push(key)
return acc
}, [])
return {
keyword,
'Max months': maxMonths,
}
})
console.log(months)
这是适合您的解决方案
const data = [
{ 'keyword': 'foo', 'search_vol': 0, 'jul-20': 10, 'aug-20': 10, 'sep-20': 10, 'oct-20': 10, 'nov-20': 10, 'dec-20': 10, 'jan-21': 10, 'feb-21': 10, 'mar-21': 10, 'apr-21': 20, 'may-21': 10, 'jun-21': 10, 'drain': 'FALSE', 'toilet': 'TRUE' },
{ 'keyword': 'faa', 'search_vol': 100, 'jul-20': 880, 'aug-20': 880, 'sep-20': 880, 'oct-20': 880, 'nov-20': 880, 'dec-20': 880, 'jan-21': 1000, 'feb-21': 880, 'mar-21': 1000, 'apr-21': 720, 'may-21': 880, 'jun-21': 880, 'drain': 'TRUE', 'toilet': 'TRUE' }
];
const expected = data.map(_obj => {
// convert object to an array and filter out the values that are not needed
const filteredArr = Object.entries(_obj)
.filter(entry => !['keyword', 'search_vol'].includes(entry[0]))
.slice(0, 12);
// find the max value in the array
const max = Math.max(...filteredArr.map(entry => entry[1]));
// find the list of months with max value
const maxMonths = filteredArr.filter(entry => entry[1] === max).map(entry => entry[0]);
return {
..._obj,
'Max Months': maxMonths
}
})
console.log(expected);
@abranhe 的回答很好,但我仍然担心依赖键的顺序。当您执行 Object.keys
.
时,键将被排序
你可以替换这个:
const filteredArr = Object.entries(_obj)
.filter(entry => !['keyword', 'search_vol'].includes(entry[0]))
.slice(0, 12);
有了这个:
const filteredArr = Object.entries(_obj)
.filter(entry => entry[0].match(/[a-z]{3}-[0-9]{2}/) !== null)
随着代码的不断变化,这会更加健壮:)
我正在尝试处理对象数组中的一些属性。
顺序总是一样的,因为在第二个 属性 之后总是接下来的 12 个条目的日期范围,之后的所有内容都被排除在外,有时可以是两个,就像在这个例子中或者可能更多。
所以我想做的是排除除关键字和日期范围之外的所有内容。
const data = [{
"keyword": "foo",
// This key never changes
"search_vol": 0,
// These keys can change when they start, i.e. starts jan-21
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
// These would change to different properties in name and amount
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"drain": "TRUE",
"toilet": "TRUE"
}]
我想这样做,以便稍后我可以获得每个对象日期的最大值,并有一个条目包含达到该最大值的月份
预期最终输出:
const data = [{
"keyword": "foo",
"search_vol": 0,
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
"Max months": ['apr-21'],
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"Max months": ['jan-21','mar-21'],
"drain": "TRUE",
"toilet": "TRUE"
}]
是否值得将流程分开,先搁置日期,然后获取最大值,还是最好一次完成所有流程?
这是我的尝试,不包括与数据的合并,但我认为过于复杂
const data = [{
"keyword": "foo",
"search_vol": 0,
"jul-20": 10,
"aug-20": 10,
"sep-20": 10,
"oct-20": 10,
"nov-20": 10,
"dec-20": 10,
"jan-21": 10,
"feb-21": 10,
"mar-21": 10,
"apr-21": 20,
"may-21": 10,
"jun-21": 10,
"drain": "FALSE",
"toilet": "TRUE"
}, {
"keyword": "faa",
"search_vol": 100,
"jul-20": 880,
"aug-20": 880,
"sep-20": 880,
"oct-20": 880,
"nov-20": 880,
"dec-20": 880,
"jan-21": 1000,
"feb-21": 880,
"mar-21": 1000,
"apr-21": 720,
"may-21": 880,
"jun-21": 880,
"drain": "TRUE",
"toilet": "TRUE"
}]
const headers = Object.keys(data[0]).filter((_, index) => index === 0 || ( index >= 1 && index <= 13))
const dates = data.reduce((acc, obj) => {
const filtered = headers.reduce((entries, key) => ({ ...entries, [key]: obj[key] }), {})
acc.push(filtered)
return acc
}, [])
const months = dates.map(({ keyword, ...dates }) => {
const max = Math.max(...Object.values(dates))
const maxMonths = Object.entries(dates).reduce((acc, [key, value]) => {
if (value === max) acc.push(key)
return acc
}, [])
return {
keyword,
'Max months': maxMonths,
}
})
console.log(months)
这是适合您的解决方案
const data = [
{ 'keyword': 'foo', 'search_vol': 0, 'jul-20': 10, 'aug-20': 10, 'sep-20': 10, 'oct-20': 10, 'nov-20': 10, 'dec-20': 10, 'jan-21': 10, 'feb-21': 10, 'mar-21': 10, 'apr-21': 20, 'may-21': 10, 'jun-21': 10, 'drain': 'FALSE', 'toilet': 'TRUE' },
{ 'keyword': 'faa', 'search_vol': 100, 'jul-20': 880, 'aug-20': 880, 'sep-20': 880, 'oct-20': 880, 'nov-20': 880, 'dec-20': 880, 'jan-21': 1000, 'feb-21': 880, 'mar-21': 1000, 'apr-21': 720, 'may-21': 880, 'jun-21': 880, 'drain': 'TRUE', 'toilet': 'TRUE' }
];
const expected = data.map(_obj => {
// convert object to an array and filter out the values that are not needed
const filteredArr = Object.entries(_obj)
.filter(entry => !['keyword', 'search_vol'].includes(entry[0]))
.slice(0, 12);
// find the max value in the array
const max = Math.max(...filteredArr.map(entry => entry[1]));
// find the list of months with max value
const maxMonths = filteredArr.filter(entry => entry[1] === max).map(entry => entry[0]);
return {
..._obj,
'Max Months': maxMonths
}
})
console.log(expected);
@abranhe 的回答很好,但我仍然担心依赖键的顺序。当您执行 Object.keys
.
你可以替换这个:
const filteredArr = Object.entries(_obj)
.filter(entry => !['keyword', 'search_vol'].includes(entry[0]))
.slice(0, 12);
有了这个:
const filteredArr = Object.entries(_obj)
.filter(entry => entry[0].match(/[a-z]{3}-[0-9]{2}/) !== null)
随着代码的不断变化,这会更加健壮:)