littlechad
littlechad

Reputation: 1228

resctructuring json from csv

I got a csv file that i manage to convert to json, and i got this

[{
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_a',
  level_of_experience: '1-2 years',
  type: 'media_type_a',
  price: 'price_for_media_type_a',
  work_sample: 'sample_for_media_type_a_1'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_a',
  level_of_experience: '1-2 years',
  type: 'media_type_a',
  price: 'price_for_media_type_a',
  work_sample: 'sample_for_media_type_a_2'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_a',
  level_of_experience: '1-2 years',
  type: 'media_type_b',
  price: 'price_for_media_type_b',
  work_sample: 'sample_for_media_type_b_1'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_a',
  level_of_experience: '1-2 years',
  type: 'media_type_b',
  price: 'price_for_media_type_b',
  work_sample: 'sample_for_media_type_b_2'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_b',
  level_of_experience: '3-5 years',
  type: 'media_type_c',
  price: 'price_for_media_type_c',
  work_sample: 'sample_for_media_type_c_1'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_b',
  level_of_experience: '3-5 years',
  type: 'media_type_c',
  price: 'price_for_media_type_c',
  work_sample: 'sample_for_media_type_c_1'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_b',
  level_of_experience: '3-5 years',
  type: 'media_type_d',
  price: 'price_for_media_type_d',
  work_sample: 'sample_for_media_type_d_1'
}, {
  first_name: 'account#1',
  last_name: 'lastname#1',
  email: '[email protected]',
  category: 'category_b',
  level_of_experience: '3-5 years',
  type: 'media_type_d',
  price: 'price_for_media_type_d',
  work_sample: 'sample_for_media_type_d_2'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_c',
  level_of_experience: '1-2 years',
  type: 'media_type_ab',
  price: 'price_for_media_type_ab',
  work_sample: 'sample_for_media_type_ab_1'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_c',
  level_of_experience: '1-2 years',
  type: 'media_type_ab',
  price: 'price_for_media_type_ab',
  work_sample: 'sample_for_media_type_ab_2'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_c',
  level_of_experience: '1-2 years',
  type: 'media_type_cd',
  price: 'price_for_media_type_cd',
  work_sample: 'sample_for_media_type_cd_1'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_c',
  level_of_experience: '1-2 years',
  type: 'media_type_cd',
  price: 'price_for_media_type_cd',
  work_sample: 'sample_for_media_type_cd_2'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_d',
  level_of_experience: '3-5 years',
  type: 'media_type_ef',
  price: 'price_for_media_type_ef',
  work_sample: 'sample_for_media_type_ef_1'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_d',
  level_of_experience: '3-5 years',
  type: 'media_type_ef',
  price: 'price_for_media_type_ef',
  work_sample: 'sample_for_media_type_ef_1'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_d',
  level_of_experience: '3-5 years',
  type: 'media_type_gh',
  price: 'price_for_media_type_gh',
  work_sample: 'sample_for_media_type_gh_1'
}, {
  first_name: 'account#2',
  last_name: 'lastname#2',
  email: '[email protected]',
  category: 'category_d',
  level_of_experience: '3-5 years',
  type: 'media_type_gh',
  price: 'price_for_media_type_gh',
  work_sample: 'sample_for_media_type_gh_2'
}]

By doing combination of lodash map, groupby, and reduce, i manage to solve it down to this

[{
  "first_name": "account#1",
  "last_name": "lastname#1",
  "email": "[email protected]",
  "details": {
    "portfolio": {
      "category_data": {
        "category_a": {
          "portfolio_type_data": {
            "media_type_a": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_b": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_c": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_d": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            }
          }
        },
        "category_b": {
          "portfolio_type_data": {
            "media_type_a": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_b": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_c": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_d": {
              "cost": "price_for_media_type_a",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            }
          }
        }
      }
    }
  }
}, {
  "first_name": "account#2",
  "last_name": "lastname#2",
  "email": "[email protected]",
  "details": {
    "portfolio": {
      "category_data": {
        "category_c": {
          "portfolio_type_data": {
            "media_type_ab": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_cd": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_ef": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_gh": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            }
          }
        },
        "category_d": {
          "portfolio_type_data": {
            "media_type_ab": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_cd": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_ef": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            },
            "media_type_gh": {
              "cost": "price_for_media_type_ab",
              "sample_file": [
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null
              ]
            }
          }
        }
      }
    }
  }
}]

while i want it to be like this

{  
  "first_name":"account#1",
  "last_name":"lastname#1",
  "details":{  
     "portfolio":{  
        "category_data":{
          ...
           "category_a":{         
              ...
              "portfolio_type_data":{  
                 "media_type_a":{  
                    "price":"price_for_media_type_a",
                    "sample_file":["sample_for_media_type_a_1", "sample_for_media_type_a_2"]
                 },
                 "media_type_b":{  
                    "price":"price_for_media_type_b",
                    "sample_file":["sample_for_media_type_b_1", "sample_for_media_type_b_2"]
                 }
              }
              ...
           },
           "category_b":{         
              ...
              "portfolio_type_data":{  
                 "media_type_c":{  
                    "price":"price_for_media_type_c",
                    "sample_file":["sample_for_media_type_c_1", "sample_for_media_type_c_2"]
                 },
                 "media_type_d":{  
                    "price":"price_for_media_type_d",
                    "sample_file":["sample_for_media_type_d_1", "sample_for_media_type_d_2"]
                 }
              }
              ...
           },
        }
     }
  }
}

And here is my jsfiddle

Upvotes: 0

Views: 43

Answers (1)

Antonio Narkevich
Antonio Narkevich

Reputation: 4336

I think it makes sense to refactor and do it in one iteration (basically as @toastal suggested). Here is how you can acheive this with some lodash magic.

let reducedData = _.reduce(csvData, (memo, value) => {
	let userInfo = {
		first_name: value.first_name,
		last_name: value.last_name,
		email: value.email,
		level_of_experience: value.level_of_experience
	};

	//Search for user info, and push into memo if not found
	let user = _.find(memo, userInfo);

	if (!user) {
		memo.push(userInfo);
		user = userInfo;
	}

	//Same trick with portfolio type. Lodash allows to check nested path with _.get call
	const typePropertyPath = `details.portfolio.category_data.${value.category}.portfolio_type_data.${value.type}`;
	let typeData = _.get(user, typePropertyPath);

	if (typeData) {
		typeData.sample_file.push(value.work_sample);
	} else {
		//Set if not found (lodash takes care of nesting)
		_.set(user, typePropertyPath, {
			price: value.price,
			sample_file: [value.work_sample]
		});
	}

	return memo;
}, []);

Hope this helps.

Upvotes: 1

Related Questions