0

I have an array of objects like this:

[
  {
    x_issue: 'Cost, Taste, Other',
    y_a_issue: 'Spillover'
  },
  {
    x_issue: 'Cost, Taste',
    y_a_issue: 'Spillover'
  },
  {
    x_issue: 'Taste, Other',
    y_a_issue: 'Packaging'
  }
]

I need the result array to be like this:

{
  "x": {
    "response": {
      "Cost": 2,
      "Taste": 3,
      "Other": 2
    }
  },
  "y_a": {
    "response": {
      "Spillover": 2,
      "Packaging": 1
    }
  }
}

Also, I have an array of parameters

['x', 'y_a', 'z']

Here there could many more parameters like x, y. the last string issue remains constant in every parameter. And it is grouped by the occurrence.
Cost has been entered twice, Taste entered thrice.

How can I do that in javascript? I am using lodash.

This is what I was trying: Here data is the array of object which is a mongodb object. And parameters is the array of parameters that I mentioned above.

let obj = {};
                _.forEach(data, (v, k) => {
                    obj.parameters = [];
                    _.forIn(v.toJSON(), (val, key) => {
                        // let count = 0;
                        var bucket = _.find(parameters, k => _.startsWith(key, k));

                        if (bucket) {

                            if (key === `${bucket}_issue`) {
                                obj[bucket] = obj[bucket] || {};
                                obj[bucket]["response"] = obj[bucket]["response"] || {};
                                obj[bucket]["response"]["all"] = obj[bucket]["response"]["all"] || [];
                                obj[bucket]["response"]["all"].push(_.words(val));

                            }
                        }
                    });
                });
7
  • Why was it downvoted? Commented Aug 10, 2016 at 18:07
  • 2
    I didn't downvote you and I really wish people wouldn't drive-by downvote (and actually explain their issue), but I would imagine that it is because you didn't post any attempts at solving this or describe what you had tried so far - it kind of looks like you came across a problem and decided to ask SO to solve it for you without trying (not saying this is the case)? idk, just a guess Commented Aug 10, 2016 at 18:19
  • I reached halfway through the problem. And couldn't proceed further. I'll post what I was trying. Commented Aug 10, 2016 at 18:30
  • @RobM. Updated the question. Commented Aug 10, 2016 at 18:36
  • Good deal, I upvoted you back to 0 :) Commented Aug 10, 2016 at 18:36

2 Answers 2

1

In pure javascript you could do it like this using forEach() loop

var data = [{
  x_issue: 'Cost, Taste, Other',
  y_a_issue: 'Spillover'
}, {
  x_issue: 'Cost, Taste',
  y_a_issue: 'Spillover'
}, {
  x_issue: 'Taste, Other',
  y_a_issue: 'Packaging'
}]

var o = {}
data.forEach(function(e) {
  Object.keys(e).forEach(function(k) {
    var p = e[k].split(', ');
    var re = /\_(?:.(?!\_))+$/
    var key = k.split(re)[0];
    if (!o[key]) o[key] = {response: {}};
    p.forEach(function(a) {
      o[key].response[a] = (o[key].response[a] || 0) + 1;
    })
  })
})

document.body.innerHTML = '<pre>' + JSON.stringify(o, 0, 4) + '</pre>';

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

2 Comments

Can you check the edited question? I am sorry, I forgot a case.
can you also check my attempt at solving it? I don't really how to proceed after that.
1

You can use _.mergeWith() with a customizer function to achieve the merge you want, and then loop the result with _.transform() to remove the `_issue from each key:

var arr = [{
  x_issue: 'Cost, Taste, Other',
  y_a_issue: 'Spillover'
}, {
  x_issue: 'Cost, Taste',
  y_a_issue: 'Spillover'
}, {
  x_issue: 'Taste, Other',
  y_a_issue: 'Packaging'
}];

/** Create the mergeWithResponse method **/
var mergeWithResponse = _.partialRight(_.mergeWith, function(ov, sv) {
  var oValue = ov ? ov : { // if the original value is undefined initialize it with a response property
    response: {}
  };
  return sv.split(',').reduce(function(final, word) { // split the words of the source value and iterate them
    var w = word.trim(); // remove space before and after the words
    final.response[w] = (final.response[w] || 0) + 1; // add the word to the response and / or increment the counter
    return final; // return the final value with the response object
  }, oValue);
});

var result = _(mergeWithResponse.apply(_, [{}].concat(arr))) // add an empty object to the beginning of the array, and apply the new array as paramaters for mergeWithResponse
  .transform(function(result, value, key) { // remove the "_issue" string an from each key, and create an object with the new keys
    var k = key.replace('_issue', '');
    result[k] = value;
  });

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.2/lodash.min.js"></script>

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.