需要合并数组中的值

时间:2018-04-12 18:27:29

标签: javascript lodash ecmascript-5

我有一组与此类似的数据:

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

我需要找到一种方法来获得每个字符串的可引用分层计数 例如,有多少L1-1选择? 3
在L1-1中,有多少是L1.0-2选择? 2
L1-1 => L1.0-2,L1.0.0-1选择了多少? 1
L1-1 => L1.0-2,有多少是L1.0.0-2选择? 1
L1-2选择了多少? 2
......等

我怀疑我需要以某种方式创建某种可用的阵列桶来管理计数,但我似乎无法控制数据结构的样子。

我应该如何获得我需要的结果呢? 我正在使用Es5和lodash库。

3 个答案:

答案 0 :(得分:1)

您可以使用函数reduce和函数forEach来计算每个令牌。

此方法生成如下对象:

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

键是组合,值是计数。

使用该对象,按键获取计数的权限非常快。

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>

答案 1 :(得分:1)

你可以只计算以连接的问题字符串开头的给定字符串。

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

答案 2 :(得分:0)

您可以构建一个嵌套对象,其中包含每个子级别的键和count属性,以指示该级别出现的次数,例如

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

这可以通过类似

的方式实现

&#13;
&#13;
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)
&#13;
&#13;
&#13;

然后,您可以手动或以编程方式检查answers对象,以找到您的答案。我相信上面的代码应该适用于任何深度和混合深度。