【问题标题】:Populate array with javascript objects. Objects chosen by comparing two String values用 javascript 对象填充数组。通过比较两个字符串值选择的对象
【发布时间】:2016-03-01 13:33:09
【问题描述】:

我有一个如下所示的对象:

parentObj:{

    nodes: [
        {
            nodeId : 'AAA',
            nodeType : 'bottom'
        },
        {
            nodeId : 'BBB',
            nodeType : 'top'
        },
        {
            nodeId : 'CCC',
            nodeType : 'bottom'
        },
        {
            nodeId : 'DDD',
            nodeType : 'top'
        },
        {
            nodeId : 'EEE',
            nodeType : 'bottom'
        },
        {
            nodeId : 'FFF',
            nodeType : 'middle'
        },
        {
            nodeId : 'GGG',
            nodeType : 'middle'
        },
        {
            nodeId : 'HHH',
            nodeType : 'bottom'
        },
        {
            nodeId : 'III',
            nodeType : 'middle'
        }
    ],

    owners: {
        'Johnson' : [ 'AAA', 'BBB', 'DDD', 'III' ], /* node ids to indicate Johnson owns these nodes */
        'Smith' : [ 'XXX', 'GGG', 'EEE', 'FFF' ] /* node ids to indicate Smith owns these nodes */
    }

}

我想做的是编写一个函数,它传入所有者名称和节点类型,并输出一个属于该所有者并且与指定节点类型匹配的节点数组。

例如,

var getNodes = function('Johnson', 'top'){
    var ret;

    /* some logic I've yet to understand... */

    return ret;
}


/* ret would look like this */

ret = [

        {
            nodeId : 'BBB',
            nodeType : 'top'
        },
        {
            nodeId : 'DDD',
            nodeType : 'top'
        }
]

所以只有属于 Johnson 并且类型为 top 的节点才会填充我的数组。

如果可能的话,我最好使用下划线来完成此操作?

有人有什么建议或意见吗?

【问题讨论】:

  • 我确信投反对票是合理的,但解释会帮助我解决未来的问题
  • 很简单:看起来你在发布问题之前没有尝试过任何事情。
  • @YuryTarabanko 啊,我明白了。好吧,事实恰恰相反,但我尽量让问题保持干净整洁。不过感谢您的解释。

标签: javascript arrays underscore.js


【解决方案1】:
function getNodes(ownerName, nodeType){
    return _.chain(parentObj.nodes)
            .filter(function(d){ 
                return _.contains(parentObj['owners'][ownerName], d.nodeId);
            })
            .where({'nodeType': nodeType})
            .value();
}

【讨论】:

    【解决方案2】:

    可以使用 _.filter 方法处理下划线 你可以做类似的事情

    var ret=_.filter(parentObj,function(val){return val.nodeType=="top"})
    

    【讨论】:

      【解决方案3】:

      使用reduce 构建所有者拥有的项目缓存,并使用filter 实际过滤节点列表。

      function getNodes(owner, type) {
         var belongsToOwner = data.owners[owner].reduce(function(acc, name){ 
            return acc[name] = 1, acc;
         }); 
      
         return data.nodes.filter(function(node) {
            return node.nodeType === type && belongsToOwner[node.nodeId]
         });
      }
      

      【讨论】:

        【解决方案4】:

        它应该可以工作:

        var getNodes = function(owner, position){
            var ret=[];
            var nodes = parentOb.owners[owner];
            _.each(nodes, function(node){
                ret = ret.concat(_.findWhere(parentObj.nodes, {"nodeId": node.nodeId, "nodeType": position}));
            })
        
            return ret;
        };
        

        【讨论】:

          【解决方案5】:

          我认为使用过滤器可以解决您的问题。

          var getNodes = function(name, type){
              var ret = _.filter(parentObj.nodes, function(node) {
                  return node.nodeType === type && _.contains(parentObj.owners[name], node.nodeId
              }
          
              return _.uniq(ret);
          }
          

          【讨论】:

            【解决方案6】:

            此提议迭代对象并返回一个包含所需结果的数组。

            function getNodes(owner, nodeType) {
                return data.parentObj.nodes.filter(function (a) {
                    return a.nodeType === nodeType && ~data.parentObj.owners[owner].indexOf(a.nodeId);
                });
            }
            
            var data = { parentObj: { nodes: [{ nodeId: 'AAA', nodeType: 'bottom' }, { nodeId: 'BBB', nodeType: 'top' }, { nodeId: 'CCC', nodeType: 'bottom' }, { nodeId: 'DDD', nodeType: 'top' }, { nodeId: 'EEE', nodeType: 'bottom' }, { nodeId: 'FFF', nodeType: 'middle' }, { nodeId: 'GGG', nodeType: 'middle' }, { nodeId: 'HHH', nodeType: 'bottom' }, { nodeId: 'III', nodeType: 'middle' }], owners: { 'Johnson': ['AAA', 'BBB', 'DDD', 'III'], 'Smith': ['XXX', 'GGG', 'EEE', 'FFF'] } } },
                result = getNodes('Johnson', 'top');
            
            document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

            【讨论】:

              【解决方案7】:

              试试这个

              var name = "Johnson";
              var type = "top"; 
              var getNodes = function( name, type ){
                  var ret = [];
                  var nodes = parentObj.owners[name];
                  for ( var counter = 0; counter < parentObj.nodes.length; counter++ )
                  {
                     if ( nodes.indexOf( parentObj.nodes[ counter ].nodeId ) != -1  && parentObj.nodes[ counter ].nodeType == type )
                     {
                         ret.push( parentObj.nodes[ counter ] );
                     }
                  }
              
                  return ret;
              }; 
              console.log(getNodes( name, type ));
              

              【讨论】:

              • 那个代码到处都有bug ... :|
              • 最后一行的错误 ... console.leg(ret) ... 解释器会告诉你 ret 没有定义。
              • @Aukhan 你运行代码了吗?无论如何现在使用返回的值。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-10-23
              • 2023-01-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多