【问题标题】:How to filter the object using lodash or javascript如何使用 lodash 或 javascript 过滤对象
【发布时间】:2016-10-30 15:09:46
【问题描述】:

我正在从服务器获取这样的对象,

var data = {
  test1: {
    documents: []
  },
  test2: {
    documents: [{
      vId: 'sdfas23',
      TypeId: '81',
      isDeleted: false
    }],
    answer: true
  },
  test3: {
    documents: [{
      vId: 'H1mJinyI',
      TypeId: '82',
      isDeleted: false
    }],
    answer: true
  }
}

我想从对象中过滤typeId,我期望的结果是

[81,82]

有人可以帮忙吗?

【问题讨论】:

  • 您在尝试编写相关代码时取得了多大的进展?你在哪里卡住了?出了什么问题?
  • 我曾经遇到过类似的用例,我使用了 lodash map()。在此处阅读 cos:lodash.com/docs#map

标签: javascript arrays node.js lodash


【解决方案1】:

如果您在 documents 中只有一个或零个对象,就像在您的示例中一样,您可以使用 reduce()Object.keys()

var data = {"test1":{"documents":[]},"test2":{"documents":[{"vId":"sdfas23","TypeId":"81","isDeleted":false}],"answer":true},"test3":{"documents":[{"vId":"H1mJinyI","TypeId":"82","isDeleted":false}],"answer":true}}

var result = Object.keys(data).reduce(function(a, e) {
  if (data[e].documents[0]) a.push(data[e].documents[0].TypeId);
  return a;
}, [])

console.log(result)

对于documents 数组中的多个对象,您可以将forEach 循环添加到之前的代码中,这样就可以得到这个(test3.documents 中有两个对象)

var data = {"test1":{"documents":[]},"test2":{"documents":[{"vId":"sdfas23","TypeId":"81","isDeleted":false}],"answer":true},"test3":{"documents":[{"vId":"H1mJinyI","TypeId":"82","isDeleted":false},{"vId":"Random","TypeId":"100","isDeleted":false}],"answer":true}}

var result = Object.keys(data).reduce(function(a, e) {
  if (data[e].documents.length) data[e].documents.forEach(function(p) {
    a.push(p.TypeId);
  });
  return a;
}, [])

console.log(result);

【讨论】:

  • @RIYAJ KHAN 谢谢。
  • 为什么要为 forEach 添加长度检查?
  • @Rajesh 长度检查被添加以消除带有documents = [] 的元素,这对于data.test1.documents 是正确的
【解决方案2】:

您只需一行代码就可以做到这一点:

_.map(_.flatten(_.map(_.values(data), 'documents')), 'TypeId');

这将产生:

["81", "82"]

【讨论】:

    【解决方案3】:

    这会为您提供预期的结果,但不确定您是否会满意

    var data=  { 
        test1: { documents: [] },
        test2: { documents: [{ vId: 'sdfas23',
              TypeId: '81',
              isDeleted: false }], answer: true },
        test3:
         { documents:
            [{ vId: 'H1mJinyI',
              TypeId: '82',
              isDeleted: false }],
           answer: true } 
    } 
    
    function getIds(array) {
        var ret = [];
        for (key in data) {
            for (key2 in data[key].documents) {
                ret.push(data[key].documents[key2].TypeId)
             }
        }
        return ret
    }
    
    console.log(getIds(data));
    

    【讨论】:

      【解决方案4】:

      你可以这样做:

      1. 以某种方式访问​​每个对象,您可以使用相同的表达式。 for...in 将帮助您获取对象的键,您可以使用data[key] 获取对象。
      2. 现在,一旦我们有了对象,我们就知道去哪里找,即obj.documents。现在文档是一个数组,我们需要在其中的每个对象中获取TypeId。为此,您可以有一个数组并在其中手动推送值,也可以使用Array.map
      3. 现在,如果您使用.map,它将为每个对象返回一个数组。因此,您必须使用array.concat 将其附加到相同的功能。但如果您使用.push,则跳过此步骤。

      对于..in + .map + .concat

      var data={test1:{documents:[]},test2:{documents:[{vId:"sdfas23",TypeId:"81",isDeleted:!1}],answer:!0},test3:{documents:[{vId:"H1mJinyI",TypeId:"82",isDeleted:!1}],answer:!0}};
      
      var r = [];
      for(var k in data){
        r = r.concat(data[k].documents.map(function(o){return o.TypeId}));
      }
      
      console.log(r)

      【讨论】:

      • @Downvoter,请评论答案中缺少的内容。
      • 我不是反对者,我知道您有一个很好的解决方案,但请提供一些解释,以便初学者和其他人将从这个好的答案中受益。
      • @hamism 我已经更新了答案。希望它能正确解释。
      【解决方案5】:

      如果属性“文档”总是只有一个对象,只需使用_.compact(_.map(data, 'documents[0].TypeId'));

      如果属性“文档”有很多对象,请使用_.flatten(_.map(data, (item) => _.map(item.documents, 'TypeId')));

      示例 - https://jsfiddle.net/qvkctvho/1/

      【讨论】:

        【解决方案6】:

        这是先前答案的另一个简化版本(没有 reducefancy 东西只有地图):

        var data=  { test1: { documents: [] },
                     test2: { documents: [{ vId: 'sdfas23', TypeId: '81', isDeleted: false },{ vId: 'sdfas23', TypeId: '85', isDeleted: false }], answer: true },
                     test3: { documents: [{ vId: 'H1mJinyI', TypeId: '82', isDeleted: false }], answer: true } 
        };
        
        var getTypeIds = function(data){
            var ids = [];
           // get object keys in this case : test1,test2,test3
            Object.keys(data).map(function(key){        
                // loop through each document attribute and extract TypeId attributes
                data[key].documents.map(function(item){                                                
                                            ids.push(item.TypeId);                                    
                                        });
        
        
            })
            return ids;   
        }
        
        console.log(getTypeIds(data)); // [ '81', '85', '82' ]
        

        【讨论】:

          【解决方案7】:

          试试这个

          Object.getOwnPropertyNames(data).map(function(val, key) {    
              return data[val].documents[0] ? data[val].documents[0].TypeId : '';    
          })
          

          【讨论】:

            【解决方案8】:

            你可以使用 lodash 的 _.map 函数来得到你想要的结果。这是示例代码 -

            var result = _.map(data, function(v,i){
                if(_.isArray(v.documents)) {
                    return v.documents[0].TypeId
                }
            
                return ''
            }
            

            【讨论】:

              【解决方案9】:

              在 lodash 中解决此问题的最简单方法是使用 flatMap() 获取 documentsmap() 的扁平数组以获取所有 TypeId

              var result = _(data)
              .flatMap('documents')
              .map('TypeId')
              .value();
              

              var data = {
                test1: {
                  documents: []
                },
                test2: {
                  documents: [{
                    vId: 'sdfas23',
                    TypeId: '81',
                    isDeleted: false
                  }],
                  answer: true
                },
                test3: {
                  documents: [{
                    vId: 'H1mJinyI',
                    TypeId: '82',
                    isDeleted: false
                  }],
                  answer: true
                }
              };
              
              var result = _(data)
              .flatMap('documents')
              .map('TypeId')
              .value();
              
              console.log(result);
              <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

              使用 ES6 的普通 JS 解决方案应该是这样的:

              var result = Object.keys(data) // get keys as reference when mapping
              .map(v => data[v].documents || []) // get all documents
              .reduce((x, y) => x.concat(y)) // flatten
              .map(v => v.TypeId); // get TypeId
              

              var data = {
                test1: {
                  documents: []
                },
                test2: {
                  documents: [{
                    vId: 'sdfas23',
                    TypeId: '81',
                    isDeleted: false
                  }],
                  answer: true
                },
                test3: {
                  documents: [{
                    vId: 'H1mJinyI',
                    TypeId: '82',
                    isDeleted: false
                  }],
                  answer: true
                }
              };
              
              var result = Object.keys(data)
              .map(v => data[v].documents || [])
              .reduce((x, y) => x.concat(y))
              .map(v => v.TypeId);
              
              console.log(result);

              【讨论】:

                猜你喜欢
                • 2015-08-23
                • 1970-01-01
                • 2021-01-19
                • 2016-11-17
                • 1970-01-01
                • 2021-01-06
                • 1970-01-01
                • 2018-08-22
                相关资源
                最近更新 更多