Home > Mobile >  How to get nested Javascript object when depth is unknown?
How to get nested Javascript object when depth is unknown?

Time:05-26

Suppose I have these arrays:

const array1 = [
   {
      data: {
         site: {
            tag: {
               name: "Bikes", 
               posts: { ... }
            }
         }
      },
      errors: {}
   },
   { ... }   
]

const array2 = [
   {
      data: {
         category: {
            name: "Cars", 
            posts: { ... }
         }
      },
      errors: {}
   },
   { ... }   
]

const array3 = [
   {
      data: {
         posts: { ... }
      },
      errors: {}
   }, 
   { ... }  
]

What function can I use on array 1 and 2 so that I am always left with an array shaped like array 3? How can I always extract posts from data without knowing at what position it is in the nested object?

I've tried a few things with find or filter or recursive functions but I'm just no good at this, sorry. Hope somebody can help!

CodePudding user response:

If there might be only these two structures then you can manually extract posts based on whether data contains the site field or the category field.

const extractPosts = ({data, errors})=>{
    return {
        data: {
            posts: data.site ? data.site.tag.posts : data.category.posts
        },
        errors
    }
}

const unknownStructureArray = [{
    data: {
        site: {
            tag: {
                name: "Bikes",
                posts: {
                    type: 'primary'
                }
            }
        }
    },
    errors: {}
}, {
    data: {
        category: {
            name: "Cars",
            posts: {
                type: 'secondary'
            }
        }
    },
    errors: {}
}, ];

const array3 = unknownStructureArray.map(extractPosts);

CodePudding user response:

I'd suggest using a recursive approach, creating a function findPosts() that will walk through an object to find any posts.

We'd also create a convertArr() function that will map an input array to the desired shape:

const array1 = [
   {
      data: {
         site: {
            tag: {
               name: "Bikes", 
               posts: { 'post1': {}, 'post2': {} }
            }
         }
      },
      errors: {}
   },
   {
      data: {
         site: {
            tag: {
               name: "Stuff", 
               posts: { 'postA': {}, 'postB': {} }
            }
         }
      },
      errors: {}
   }
]

const array2 = [
   {
      data: {
         category: {
            name: "Cars", 
            posts: { post1: 'Some post', post2: 'Another post '}
         }
      },
      errors: {}
   }
]

function findPosts(input) { 
    for(let key in input) {
        if (key === 'posts') {
            return input[key];
        } else if (input[key] && (typeof(input[key]) === 'object')) {
            let posts = findPosts(input[key]);
            if (posts) {
                return posts;
            }
        }
    }
    return null;
}

function convertArr(arr) {
    return arr.map(el => { 
        return { 
            data: { posts: findPosts(el) },
            errors: el.errors
        };
    })
}

console.log('Array1:', convertArr(array1));
console.log('Array2:', convertArr(array2));
.as-console-wrapper { max-height: 100% !important; }

  • Related