1

I am trying to sort data that looks like this:

{
    "Params": [
        ["section", "North"],
        ["monitor", "Single Monitor"],
        ["section", "North"],
        ["monitor", "Dual Monitor"]
    ]
}

Into something that looks like this:

{
    "section": [
        "North"
    ],
    "monitor": [
        "Single Monitor",
        "Dual Monitor"
    ]
}

But I am currently having issues, I've tried a few different things such as concatenating the arrays together in a loop, or even using lodash's uniq function but every time I get a non desired result.

Thanks in advance for any help

1
  • 2
    "I've tried a few different things..." - Please add your most promising approach and we will try to help you with it. Commented Jun 21, 2020 at 16:33

4 Answers 4

3

You can aggregate your array of arrays using array.reduce:

let obj = {
    "Params": [
        ["section", "North"],
        ["monitor", "Single Monitor"],
        ["section", "North"],
        ["monitor", "Dual Monitor"]
    ]
}

let result = obj.Params.reduce((acc,cur) => {
   let [key,value] = cur;
   if(!acc[key]){
      acc[key] = [];
   }
   if(!acc[key].includes(value)){
      acc[key].push(value);
   }
   return acc;
}, {});

console.log(result);

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

1 Comment

why find for a single value? includes woud work better.
1

Number of operation needs to be done here. You can make use of reduce in order to group the key wise data. Since you have only key value pair array format, so in reduce I have destructured it with [k,v] indicating key and value. Then to remove duplicate values, I have used Set.

var data={
    "Params": [
        ["section", "North"],
        ["monitor", "Single Monitor"],
        ["section", "North"],
        ["monitor", "Dual Monitor"]
    ]
};

var result = data.Params.reduce((a,[k, v])=>(a[k] = [...(a[k] || []), v], a[k] = [...new Set(a[k])], a),{});

console.log(result);

Comments

1

You can use _.groupBy() the _.head() (first item of each pair) to group items. Then use _.mapValues() to iterate each group, map it to get the _.last() item, and the use _.uniq() to get just the unique values:

const data = {"Params":[["section","North"],["monitor","Single Monitor"],["section","North"],["monitor","Dual Monitor"]]};

const result = _.mapValues(
  _.groupBy(data.Params, _.head), // group by the first item
  g => _.uniq(_.map(g, _.last)) // map each group to the last item, and get unique values
);

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

With lodash lodash/fp you can generate a function using _.flow() that does the same thing:

const { flow, groupBy, head, mapValues, map, last, uniq } = _;

const fn = flow(
  groupBy(head),
  mapValues(flow(
    map(last),
    uniq
  ))
);

const data = {"Params":[["section","North"],["monitor","Single Monitor"],["section","North"],["monitor","Dual Monitor"]]};

const result = fn(data.Params);

console.log(result);
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

Comments

1

You can turn reduce() method to groupBy function as follows

let obj = {
  "Params": [
    ["section", "North"],
    ["monitor", "Single Monitor"],
    ["section", "North"],
    ["monitor", "Dual Monitor"]
  ]
};

const res = obj.Params.reduce((acc, [key, val]) => {
  acc[key] = acc[key] || [];
  if (!acc[key].includes(val)) {
    acc[key].push(val);
  }
  return acc;
}, {});
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.