我正在尝试循环并过滤包含不同数组和对象的复杂数据结构,如下所示:
// current tags to filter by
let filterTags = ['Folk', 'Professional']
// return the same data structure that has filtered out any events that dont
// have SecondaryTag.Title in the filterTags
let filteredEvents = allEvents.filter((el) => {
return filterTags.includes(el)
});
然而,数据结构由复杂的数组和对象组成,使得这非常复杂。
我尝试过各种各样的东西,这些东西让我把头撞到键盘上。而不是发布我尝试的所有荒谬的事情,我想我会发布我想要在这里完成的事情,希望有些善良的灵魂会帮助我。
let allEvents = [{
'2018': {
'03': {
'31': [
{
ID: 1,
Title: "My Project",
Date: "2018-02-27",
SecondaryTag: {
Title: "Professional"
}
}
],
'28': [
{
ID: 2,
Title: "My Project",
Date: "2018-02-27",
SecondaryTag: {
Title: "Business & Professional"
}
}
]
},
'04': {
'12': [
{
ID: 5,
Title: "My Project2",
Date: "2018-04-12",
SecondaryTag: {
Title: "concert"
}
}
],
'2': [
{
ID: 7,
Title: "My Project2",
Date: "2018-04-12",
SecondaryTag: {
Title: "Folk"
}
}
]
}
}
}];

// This would be the returned filtered structure given the tags
[{
'2018': {
'03': {
'31': [
{
ID: 1,
Title: "My Project",
Date: "2018-02-27",
SecondaryTag: {
Title: "Professional"
}
}
],
},
'04': {
'2': [
{
ID: 7,
Title: "My Project2",
Date: "2018-04-12",
SecondaryTag: {
Title: "Folk"
}
}
]
}
}
}]

答案 0 :(得分:0)
这是ES6语法中的函数。
let filtered = {}; //The object or array that will contain the filtered values
filter($toBeFiltered, $filtered, [], 0); //Run function
function filter(container, obj, keys, level) {
if (typeof container.SecondaryTag != 'undefined') { //if `SecondaryTag` is an attribute
let title = container.SecondaryTag.Title; //Get title
if (filterTags.indexOf(title) > -1) { // If title is what's filtered
setDeepValue(obj, container, keys, typeof keys[0]); // Set in `filteredEvents` object
}
return true; //Stop function
}
for (let key in container) {
let parsed = Array.isArray(container) ? parseInt(key) : key; //Detect Array vs variable
let copyKeys = [...keys]; //Copy array to prevent key lost
copyKeys[level] = parsed;
filter(container[key], obj, copyKeys, level + 1); //Run again
}
}
function setDeepValue(obj, value, keys, lastType) {
let nextType = typeof keys.slice(1, 2)[0]; // Get type of next value
if (keys.length > 1) { //If not last
let k = keys.shift(); // Get first value & shift array
if (obj[k]== null || typeof obj[k] !== 'object'){ // Create object/array if key doesn't exist
if (nextType == 'string') { obj[k] = {} } // Create array if key is a string
else if (nextType == 'number') { obj[k] = []; } // Create object if key is a number
}
setDeepValue(obj[k], value, keys, nextType); // Repeat
} else { //If value is the last, then set value
if (lastType == 'string') { obj[keys[0]] = value; } // Set value as object if key is a string
else if (lastType == 'number') { obj.push(value); } // Set value as array if key is a number
}
}
使用OP数据的示例。
let filterTags = ['Folk', 'Business & Professional'];
let allEvents = [{
'2018': {
'03': {
'31': [
{
ID: 1,
Title: "My Project",
Date: "2018-02-27",
SecondaryTag: {
Title: "Business & Professional"
}
}
],
'28': [
{
ID: 2,
Title: "My Project",
Date: "2018-02-27",
SecondaryTag: {
Title: "Business & Professional"
}
}
]
},
'04': {
'12': [
{
ID: 5,
Title: "My Project2",
Date: "2018-04-12",
SecondaryTag: {
Title: "concert"
}
}
],
'2': [
{
ID: 7,
Title: "My Project2",
Date: "2018-04-12",
SecondaryTag: {
Title: "Folk"
}
}
]
}
}
}];
let filtered = {};
filter(allEvents, filtered, [], 0);
function filter(container, obj, keys, level) {
if (typeof container.SecondaryTag != 'undefined') { //if `SecondaryTag` is an attribute
let title = container.SecondaryTag.Title; //Get title
if (filterTags.indexOf(title) > -1) { // If title is what's filtered
setDeepValue(obj, container, keys, typeof keys[0]); // Set in `filteredEvents` object
}
return true; //Stop function
}
for (let key in container) {
let parsed = Array.isArray(container) ? parseInt(key) : key; //Used later to detect Array vs Object key
let copyKeys = [...keys]; //Copy array to prevent key lost
copyKeys[level] = parsed;
filter(container[key], obj, copyKeys, level + 1); //Run again
}
}
function setDeepValue(obj, value, keys, lastType) {
let nextType = typeof keys.slice(1, 2)[0]; // Get type of next value
if (keys.length > 1) { //If not last
let k = keys.shift(); //Shift Array
if (obj[k ]== null || typeof obj[k] !== 'object') { //If the key doesn't exist or not array/object
if (nextType == 'string') { obj[k] = {} } //Set to empty object is next key is a string
else if (nextType == 'number') { obj[k] = []; } //Set to empty array is next key is a number
}
setDeepValue(obj[k], value, keys, nextType); //Repeat
} else { //If last key
/* Neccessary? */
if (lastType == 'string') { obj[keys[0]] = value; } //Set object value if last type is object
else if (lastType == 'number') { obj.push(value); } //Set array value if last type is array
}
}
console.log(filtered);
这个答案利用了Cerbrus的作品。