0

The below code will have input as array of objects and I would like to convert into a different format.

The below code works fine but I need a more refactored shorter format of what I am trying to achieve.

var res =  {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);

var res = [];
for(var key in parsedObj.data){
    var emailObj = {};
    var phoneObj = {}
    if(parsedObj.data[key].email !== null){
        emailObj.matchedRes = parsedObj.data[key].email;
        emailObj.id = parsedObj.data[key].id;
        emailObj.type = "email";
        res.push(emailObj);
    }
    if(parsedObj.data[key].phone !== null){
        phoneObj.matchedRes = parsedObj.data[key].phone;
        phoneObj.id = parsedObj.data[key].id;
        phoneObj.type="phone";
        res.push(phoneObj);
    }  
}
console.log(res);

Desired output:

[ { matchedRes: '[email protected]', id: 'jack1', type: 'email' },
  { matchedRes: '[email protected]', id: 'jack2', type: 'email' },
  { matchedRes: '+16464922600', id: 'jack2', type: 'phone' } ]

In the above code separate objects are created with phone and email for same id.

1
  • Seems pretty optimized to me :) Commented Feb 14, 2019 at 8:48

4 Answers 4

3

Here is a solution!

I just did a generic reducer, and then I use it on phone and email.

Then, I just spread the result of both calls to the result array :)

var res =  {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);

const extractData = (obj, type) => obj.reduce((acc, elt) => (
  elt[type] && acc.push({matchedRes: elt[type], id: elt.id, type: type})
, acc),[]);

const result = [...extractData(parsedObj.data, 'email'), ...extractData(parsedObj.data, 'phone')];

console.log(result);

Hope this helps, please do not hesitate to comment if you have any question ;)

Sign up to request clarification or add additional context in comments.

5 Comments

Best not to abuse the conditional operator as a replacement for if. The conditional operator is when you need a resulting expression - if you don't need an expression, the conditional operator is not appropriate
I agree with you, it is often less readable and only appropriate in some cases. But as OP asked for a shorter format... :) I gave my best to the shortest version!
You can destructuring assignment to make it even shorted stackoverflow.com/questions/54605286/…
Thanks you for the overwhelming response. Learned lot of refactoring techniques with Reduce today.
@user804401 You should google something like javascript performance map vs reduce, but from my understanding, this will be quite the same. The performance will mainly depends on your mapping/reducing function, but in the end, both functions do the same: iterating on an array, executing the function to map/reduce, then adding the result of this function in a target object. Maybe reduce is slightly heavier (not even sure about that), but I think that when you come to that kind of fine tuning issue, you will probably want to modify your data model more than using something else than reduce!
2

You can use reduce with destructuring assignment . and check if email or phone is there than add a object accordingly

var res =  {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);

let op = parsedObj.data.reduce((out,{id,email,phone})=>{
  if(email){
    out.push({matchedRes:email,id,type:`email`})
  } 
  if(phone){
  out.push({matchesRes:phone,id,type:`phone`})
  }
  return out
},[])

console.log(op)

If you want to see more use cases of You can destructuring assignment and it's uses you can check this one out

1 Comment

2

This should be possible with reduce:

var res =  {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
const keyFields = ["email", "phone"];

let result = parsedObj.data.reduce((acc, val) => {
    keyFields.forEach(k => {
       if (val[k]) acc.push({ matchedRes: val.email, id: val.id,  type: k});
    });
    return acc;
}, []);

console.log("Result: ", result);

4 Comments

You can destructuring assignment to make it even shorted stackoverflow.com/questions/54605286/…
I saw that it your answer. Nice solution!
The only slight issue with that is the OP wants the phone, email fields mapped to a matchedRes field, right?
Yeah, fixed that key naming mate. Thanks for pointing out miss
2

If you are looking for a little shorter code but still easy to read for anybody:

var res =  {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"[email protected]\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);

var res = [];

Object.entries(parsedObj.data).forEach(el => {
    el = el[1]
    if(el.email !== null)
      res.push({
        matchedRes: el.email,
        id: el.id,
        type: "email"
      })
    if(el.phone !== null)
       res.push({
        matchedRes: el.phone,
        id: el.id,
        type: "phone"
    })
})

console.log(res);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.