JavaScript:关联数组和映射

标签 javascript arrays dictionary knockout.js

我有一个技能集群的数据集:clusterName、skillSet。我还有一些静态技能查找存储库,其中包含所有技能集前缀及其集群标题。我需要为用户选择的集群列表提取集群标题和相应的技能集。我创建了一个对象。但这不适合我的情况。我只需要我创建的对象的数组。

var clusterNames = ['AX', 'BX', 'CX', 'DX']; //Sample cluster Names
var clusterLookup = ['AX:A', 'AX:B', 'AX:C', 'AX:D', 'BX:E', 'BX:F', 'BX:G', 'CX:H', 'CX:I', 'CX:J', 'CX:K', 'CX:L', 'DX:M', 'DX:N']; //Lookup 
//object skillClusterMap to store cluster and skills
var skillClusterMap = {
    'cluster': [],
    'skills':[]
};

var manyclusters = skillClusterMap([]); //array of skillClusterMap - I need something like this
var tempClusterName = ['AX', 'BX']; // observable array
for (var i = 0; i < tempClusterName.count; i++) {
    skillClusterMap.cluster.push(cluster[i]); // This is working fine
    manyclusters[1].cluster.push(tempClusterName[i]); // I need this to get work
            ko.utils.arrayFilter(clusterLookup, function (item) {
                var lstSkillclusters = item.desc.split(':');

                if (lstSkillclusters[0] === tempClusterName[i]) {
                    subClusterList.push(lstSkillclusters[1]);                            
                }
            });
            manyclusters[i].skills.push(subClusterList); // I need this to get work
}
skillClusterMap.skills.push(subClusterList); // This is working fine

具有单个条目的对象 SkillClusterMap 的最终 View ,

enter image description here

具有多个条目的对象 SkillClusterMap 的最终 View ,

enter image description here

它以一系列集群和一系列技能结束。但我需要一组集群和技能,

manyclusters[0]->cluster: 'AX' , skills: 'AX:A', 'AX:B', 'AX:C', 'AX:D'
manyclusters[1]->cluster: 'BX' , skills: 'BX:E', 'BX:F', 'BX:G'

任何建议都会有帮助。

最佳答案

我将这个答案分为两部分:

  1. 如何将一个或两个数据数组转换为包装这些数据的对象数组
  2. 如何使用 knockout.js 高效选择已创建数据的子集

1。转换数据

您应该将其视为一个简单的 JavaScript 练习,而不用担心过早被 knockout 。

从数据来看,似乎不需要名称数组就可以了,因为它们已经在技能中了。我们将减少技能数组,传递一个保存每个集群 key 的对象,指向该集群中的技能数组。

var clusterLookup = ['AX:A', 'AX:B', 'AX:C', 'AX:D', 'BX:E', 'BX:F', 'BX:G', 'CX:H', 'CX:I', 'CX:J', 'CX:K', 'CX:L', 'DX:M', 'DX:N']; //Lookup 

// Create the map, keys are cluster name, hold array of skills
var skillMap = clusterLookup.reduce(function(map, skill) {
  var key = skill.substring(0, 2); // Extract key
  map[key] = map[key] || [];      // Create array if first of key
  map[key].push(skill);
  return map;
}, {});

// Create the objects
var models = Object.keys(skillMap).map(function(key) {
  return {
    cluster: key,
    skills: skillMap[key]
  };
});

console.log(models);
.as-console-wrapper { min-height: 100%; }

2。使用 knockout 按集群选择技能

现在,如果您想根据用户输入动态创建这些集群的子集,ko.compulated 就是最佳选择。例如,您可以有一个可观察的集群名称数组,并使用该数组来选择技能:

function ViewModel(map) {
  this.selectedClusters = ko.observableArray([]); 
  
  this.allClusters = Object.keys(map);
  this.selectedSkills = ko.pureComputed(function() {
      // This is the same logic used in 1, but wrapped in a computed
      // We're taking an array of cluster names as input, creating 
      // a new array with cherry-picked skills from our previously 
      // created map
      return this.selectedClusters()
        .reduce(function(result, cluster) {
          // Create models dynamically
          return result.concat({
            cluster: cluster,
            skills: map[cluster]
          });
      }, []);
  }, this);
};


var clusterLookup = ['AX:A', 'AX:B', 'AX:C', 'AX:D', 'BX:E', 'BX:F', 'BX:G', 'CX:H', 'CX:I', 'CX:J', 'CX:K', 'CX:L', 'DX:M', 'DX:N']; //Lookup 

// Create the map, keys are cluster name, hold array of skills
var skillMap = clusterLookup.reduce(function(map, skill) {
  var key = skill.substring(0, 2); // Extract key
  map[key] = map[key] || [];      // Create array if first of key
  map[key].push(skill);
  return map;
}, {});

ko.applyBindings(new ViewModel(skillMap));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<ul data-bind="foreach: allClusters">
    <li>
      <input type="checkbox" data-bind="checkedValue: $data, checked: $parent.selectedClusters">
      <span data-bind="text: $data"></span>
    </li>
</ul>

<ul data-bind="foreach: selectedSkills">
  <li>
    <strong data-bind="text: cluster"></strong>:
    <span data-bind="text: skills"></span>
  </li>
</ul>

关于JavaScript:关联数组和映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40670765/

相关文章:

javascript - jquery:尝试理解 next() 函数

c - C-无法将文本文件中的字符串列表读取并处理到数组中

使两条对角线都通过矩阵条目 (i,j) 的 Pythonic 方法

java - Arcgis map : Get Current Location Error , 不显示我的当前位置

javascript - 如何获取页面元素?

javascript - 我怎样才能制作一个比窗口大(高度)的 div,固定但仍然可以滚动而没有任何侧边栏?

javascript - Jquery访问div问题

java - 字符串与另一个字符串重叠

java - map 上复杂操作的问题

python - 如何用 Python 将字典写入 Excel