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.
eg
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.


您可以只计算以加入的问题字符串开头的给定字符串。

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);

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:ttt",                 result['L1-1']);
console.log("L1-1_L1.0-2:tt",            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:ttt",                 result['L1-2']);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://codepen.io/egomezr/pen/dmLLwP.js"></script>

You could build a nested object with a key for each child level and a count property to indicate how many times that level occurs, eg

{
  'L1-1': {
    count: 2,
    'L1.0-1': {
      count: 1,
      ...
     },
     'L1.0-2': {
       ...
     }
    },
    ...
}

This can be accomplished with something like

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"
];

function insert(object,key) {
    if (!object[key]) {
        object[key] = {};
        object[key].count = 1;
    } else {
        object[key].count++;
    }
}

var answers = data.reduce(function(a,c) {
	var strings = c.split('_');
	strings.reduce(function(ap,cp){
		insert(ap, cp);
		return ap[cp];
	}, a)
	return a;
}, {})

console.log(answers)
链接地址: http://www.djcxy.com/p/852.html

上一篇: 为什么Facebook图形API不会列出页面的所有公共事件?

下一篇: 需要合并数组中的值