JavaScript:关联数组和映射

时间:2016-11-18 06:35:10

标签: javascript arrays dictionary knockout.js

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

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的最终视图

enter image description here

带有多个条目的对象skillClusterMap的最终视图,

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 个答案:

答案 0 :(得分:4)

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

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

    您应该将此视为一个简单的JavaScript练习,而不是过早担心淘汰赛。

    查看数据,看起来你可以不使用名字数组,因为他们已经掌握了技能。我们将reduce技能数组,传递一个包含每个集群密钥的对象,指向该集群中的一系列技能。

    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.computed。例如,您可以拥有一个可观察的群集名称数组,并使用此数组来选择技能:

    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>