Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to merge values in array

I have a set of data that looks similar to this:

[
    "L1-1_L1.0-1_L1.0.0-1",
    "L1-1_L1.0-2_L1.0.0-1",
    "L1-1_L1.0-2_L1.0.0-2",
    "L1-2_L1.0-1_L1.0.0-1",
    "L1-2_L1.0-1_L1.0.0-2",
    "L1-3_L1.0-1_L1.0.0-3"
];

I need to find a way to get a referenceable layered count of each of these strings.
e.g.
How many L1-1 selections? 3
Of the L1-1, how many were L1.0-2 selections? 2
Of the L1-1 => L1.0-2, how many were L1.0.0-1 selections? 1
Of the L1-1 => L1.0-2, how many were L1.0.0-2 selections? 1
How many L1-2 selections? 2
... etc.

I suspect that I need to somehow create some kind of refrenceable array buckets to manage the counts, but I can't seem to get a grip on what that data-structure would look like.

How should I go about getting the results I need?
I am using Es5 and lodash libraries.

like image 584
cw84 Avatar asked Apr 12 '18 18:04

cw84


2 Answers

You could just count the given strings who starts with the joined question string.

var data = ["L1-1_L1.0-1_L1.0.0-1", "L1-1_L1.0-2_L1.0.0-1", "L1-1_L1.0-2_L1.0.0-2", "L1-2_L1.0-1_L1.0.0-1", "L1-2_L1.0-1_L1.0.0-2", "L1-3_L1.0-1_L1.0.0-3"],
    questions = [['L1-1'], ['L1-1', 'L1.0-2'], ['L1-1', 'L1.0-2', 'L1.0.0-1'], ['L1-1', 'L1.0-2', 'L1.0.0-2'], ['L1-2']],
    answers = questions.map(
        q => data.reduce((r, d) => r + d.startsWith(q.join('_')), 0)
    );

console.log(answers);
like image 78
Nina Scholz Avatar answered Sep 30 '22 18:09

Nina Scholz


You can use the function reduce along with the function forEach to make a count of every token.

This approach generates an object as follow:

{
    "L1-1": 3,
    "L1-1_L1.0-1": 1,
    "L1-3_L1.0-1": 1,
    .
    .
}

The keys are the combinations and the values are the counts.

With that object, the access to get the count is super fast by key.

const samples = [ "L1-1_L1.0-1_L1.0.0-1", "L1-1_L1.0-2_L1.0.0-1", "L1-1_L1.0-2_L1.0.0-2", "L1-2_L1.0-1_L1.0.0-1", "L1-2_L1.0-1_L1.0.0-2",  "L1-3_L1.0-1_L1.0.0-3" ];

const result = samples.reduce((a, s) => {
  let previous =  "", separator = "";
  s.split("_").forEach(t => {
    previous += separator + t;
    a[previous] = (a[previous] || (a[previous] = 0)) + 1;
    separator = "_";
  });
  
  return a;
}, {});

console.log("L1-1:\t\t\t",                 result['L1-1']);
console.log("L1-1_L1.0-2:\t\t",            result['L1-1_L1.0-2']);
console.log("L1-1_L1.0-2_L1.0.0-1:\t",     result['L1-1_L1.0-2_L1.0.0-1']);
console.log("L1-1_L1.0-2_L1.0.0-2:\t",     result['L1-1_L1.0-2_L1.0.0-2']);
console.log("L1-2:\t\t\t",                 result['L1-2']);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://codepen.io/egomezr/pen/dmLLwP.js"></script>
like image 21
Ele Avatar answered Sep 30 '22 17:09

Ele