1

I would like to transform belo input.json file. I would like to merge all the category key into one and create array of names, if it matches.

I am looking for a solution using only lodash or only JS/ES*

There are similar questions already asked, but most of them involve two different json's. Please shed some light on the solution

[
    {
        "category": "Salman Khan",
        "names": "Bhaijan"
    },
    {
        "category": "Salman Khan",
        "names": "Sallu"
    },
    {
        "category": "Salman Khan",
        "names": "Dabangg Khan"
    },
    {
        "category": "Salman Khan",
        "names": "Sultan"
    },
    {
        "category": "Shahrukh Khan",
        "names": "SRK"
    },
    {
        "category": "Shahrukh Khan",
        "names": "King Khan"
    },
    {
        "category": "Akshay Kumar",
        "names": "Khiladi"
    },
    {
        "category": "Akshay Kumar",
        "names": "Akki"
    },
    {
        "category": "Aamir Khan",
        "names": "A.K."
    },
    {
        "category": "Aamir Khan",
        "names": "Mr. Perfectionist"
    },
    {
        "category": "Priyanka Chopra",
        "names": "Piggy Chops"
    },
    {
        "category": "Kareena Kapoor",
        "names": "Bebo"
    }
]

expected json

[
    {
        "category": "Salman Khan",
        "names": ["Bhaijan", "Sallu", "Dabangg Khan", "Sultan"]
    },
    {
        "category": "Shahrukh Khan",
        "names": ["SRK", "King Khan"]
    },
    {
        "category": "Akshay Kumar",
        "names": ["Khiladi", "Akki", "A.K."]
    },
    {
        "category": "Aamir Khan",
        "names": ["Mr. Perfectionist"]
    },
    {
        "category": "Priyanka Chopra",
        "names": ["Piggy Chops"]
    },
    {
        "category": "Kareena Kapoor",
        "names": ["Bebo"]
    }
]

3 Answers 3

3

Iterate over the array using Array#reduce function and check if an object already exist with the current item name. If yes, just push the name into it, if not create a new object with the current item name.

const data = [
    {
        "category": "Salman Khan",
        "names": "Bhaijan"
    },
    {
        "category": "Salman Khan",
        "names": "Sallu"
    },
    {
        "category": "Salman Khan",
        "names": "Dabangg Khan"
    },
    {
        "category": "Salman Khan",
        "names": "Sultan"
    },
    {
        "category": "Shahrukh Khan",
        "names": "SRK"
    },
    {
        "category": "Shahrukh Khan",
        "names": "King Khan"
    },
    {
        "category": "Akshay Kumar",
        "names": "Khiladi"
    },
    {
        "category": "Akshay Kumar",
        "names": "Akki"
    },
    {
        "category": "Aamir Khan",
        "names": "A.K."
    },
    {
        "category": "Aamir Khan",
        "names": "Mr. Perfectionist"
    },
    {
        "category": "Priyanka Chopra",
        "names": "Piggy Chops"
    },
    {
        "category": "Kareena Kapoor",
        "names": "Bebo"
    }
]

const arr = data.reduce((acc, item) => {
  
  const found = acc.find(i => i.category === item.category);
  
  if(found) {
     found.names.push(item.names);
  } else {
     acc.push({category: item.category, names: [item.names]})
  }
  
  return acc;
}, []);

console.log(arr);

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

2 Comments

Thanks for the quick answer, However can you explain what does the last empty parameter do }, []);
It is the signature of the reduce function. I just pass an empty array as a start value for the acc inside it
0

You can use lodash#groupBy, to group each object in the collection by the category key, and then lodash#map to transform each group into an array format of your liking.

var result = _(data)
  .groupBy('category')
  .map(function(group, category) {
    return {
      category: category,
      names: _.map(group, 'names')
    };
  })
  .value();

var data = [
    {
        "category": "Salman Khan",
        "names": "Bhaijan"
    },
    {
        "category": "Salman Khan",
        "names": "Sallu"
    },
    {
        "category": "Salman Khan",
        "names": "Dabangg Khan"
    },
    {
        "category": "Salman Khan",
        "names": "Sultan"
    },
    {
        "category": "Shahrukh Khan",
        "names": "SRK"
    },
    {
        "category": "Shahrukh Khan",
        "names": "King Khan"
    },
    {
        "category": "Akshay Kumar",
        "names": "Khiladi"
    },
    {
        "category": "Akshay Kumar",
        "names": "Akki"
    },
    {
        "category": "Aamir Khan",
        "names": "A.K."
    },
    {
        "category": "Aamir Khan",
        "names": "Mr. Perfectionist"
    },
    {
        "category": "Priyanka Chopra",
        "names": "Piggy Chops"
    },
    {
        "category": "Kareena Kapoor",
        "names": "Bebo"
    }
];

var result = _(data)
  .groupBy('category')
  .map(function(group, category) {
    return {
      category: category,
      names: _.map(group, 'names')
    };
  })
  .value();

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

Comments

0

Here's the possible solution using reduce method.

const data = [
    {
        "category": "Salman Khan",
        "names": "Bhaijan"
    },
    {
        "category": "Salman Khan",
        "names": "Sallu"
    },
    {
        "category": "Salman Khan",
        "names": "Dabangg Khan"
    },
    {
        "category": "Salman Khan",
        "names": "Sultan"
    },
    {
        "category": "Shahrukh Khan",
        "names": "SRK"
    },
    {
        "category": "Shahrukh Khan",
        "names": "King Khan"
    },
    {
        "category": "Akshay Kumar",
        "names": "Khiladi"
    },
    {
        "category": "Akshay Kumar",
        "names": "Akki"
    },
    {
        "category": "Aamir Khan",
        "names": "A.K."
    },
    {
        "category": "Aamir Khan",
        "names": "Mr. Perfectionist"
    },
    {
        "category": "Priyanka Chopra",
        "names": "Piggy Chops"
    },
    {
        "category": "Kareena Kapoor",
        "names": "Bebo"
    }
];

const resultObject = data.reduce((acc, value) => {
  acc[value.category] = acc[value.category] || [];
  acc[value.category].push(value.names);
  return acc; 
},{});

const results = Object.keys(resultObject).map(key => ({ category: key, names: resultObject[key]}));

console.log(results);

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.