如何使用Lodash访问父对象和匹配的子对象?

时间:2018-08-02 09:16:06

标签: javascript lodash

我想获取父对象的值以及所有带有ischecked标志的孩子(带有lodash)。

这是我到目前为止所拥有的:

responsetable = [{
  "Qty": 3,
  "List1": [],
  "List2": [
    {
      "serialNumber": "1",
       "ischecked":false
    },
    {
      "serialNumber": "2",
       "ischecked":true
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "lineItemId": 50,
  "lineItemQty": 3,
},
]


const filter = _.filter(this.responsetable, function (item) {
 return  _.some(item.List2, { 'ischecked': true });
});

console.dir(filter)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.core.min.js"></script>

在这里,我要从此json检查仅检查了所有要显示为对象值的孩子,所有孩子都被检查为true。 到目前为止,这是我尝试过的方法,但是它返回的是所有序列号对象,而不是将ischecked标志设置为true的对象。

从这个json

我想要qty,lineitemid和lineitemqty以及匹配的孩子。 预期输出为

   [{
    "Qty": 3,
    "List1": [],
    "List2": [

      {
        "serialNumber": "2",
         "ischecked":true;
      },
    ],
    "lineItemId": 50,
    "lineItemQty": 3,
  },
  ]      

3 个答案:

答案 0 :(得分:0)

我希望这可以。.

let responsetable  = [{
  "Qty": 3,
  "List1": [],
  "List2": [
    {
      "serialNumber": "1",
       "ischecked":false
    },
    {
      "serialNumber": "2",
       "ischecked":true
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "lineItemId": 50,
  "lineItemQty": 3,
},
]

for(var i=0; i<responsetable.length; i++){
  // checking whether List1 is empty or not
  if(responsetable[i].List1.length > 0){
    responsetable[i].List1 = responsetable[i].List1.filter((o) =>{
    return o.ischecked
  })
  }

  responsetable[i].List2 = responsetable[i].List2.filter((o) =>{
    return o.ischecked
  })
}

console.log(responsetable)

答案 1 :(得分:0)

您可能不需要lodash。 filter mapsome都内置在javascript中。

从您的问题中确切知道您的需求并不是特别容易,但是如果您只想在其列表之一中仅取那些值至少为ischecked的对象,这是一个最佳猜测: / p>

const responsetable = [{
  "Qty": 3,
  "List1": [],
  "List2": [
    {
      "serialNumber": "1",
       "ischecked":false
    },
    {
      "serialNumber": "2",
       "ischecked":true 
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "lineItemId": 50,
  "lineItemQty": 3,
},
{
  "Qty": 5,
  "List1": [
    {
      "serialNumber": "1",
       "ischecked":true
    },
    {
      "serialNumber": "2",
       "ischecked": false
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "List2": [
    
  ],
  "lineItemId": 51,
  "lineItemQty": 100,
}
]

const listHasACheckedSerial = list => list.some(listItem => listItem.ischecked)

const getResponseObjectLists = responseObject => Object.keys(responseObject)
  .filter(key => key.indexOf('List') > -1)
  .map(key => responseObject[key])

const responseObjectHasCheckedList = responseObjectIn => getResponseObjectLists(responseObjectIn)
  .map(list => listHasACheckedSerial(list))
  .some(v => !!v)

const getRequiredResponseObjectProperties = responseObject => ({
  Qty: responseObject.Qty,
  List1: responseObject.List1.filter(item => item.ischecked),
  List2: responseObject.List2.filter(item => item.ischecked),
  lineItemId: responseObject.lineItemId,
  lineItemQty: responseObject.lineItemQty,
})

const filter = responseObjects => responseObjects
  .filter(responseObject => responseObjectHasCheckedList(responseObject))
  .map(responseObject => getRequiredResponseObjectProperties(responseObject))

const test = getResponseObjectLists(responsetable[0])
const result = filter(responsetable)

console.dir(result)

但是,如果您只想检查List2中的项目:

const responsetable = [{
  "Qty": 3,
  "List1": [],
  "List2": [
    {
      "serialNumber": "1",
       "ischecked":false
    },
    {
      "serialNumber": "2",
       "ischecked":true 
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "lineItemId": 50,
  "lineItemQty": 3,
},
{
  "Qty": 5,
  "List1": [],
  "List2": [
    {
      "serialNumber": "1",
       "ischecked":false
    },
    {
      "serialNumber": "2",
       "ischecked": false
    },
    {
      "serialNumber": "3",
       "ischecked":false
    }
  ],
  "lineItemId": 51,
  "lineItemQty": 100,
}
]

const getRequiredResponseObjectProperties = responseObject => ({
  Qty: responseObject.Qty,
  List1: responseObject.List1.filter(item => item.ischecked),
  List2: responseObject.List2.filter(item => item.ischecked),
  lineItemId: responseObject.lineItemId,
  lineItemQty: responseObject.lineItemQty,
})

const filter = responseObjects => responseObjects
  .filter(r => r.List2
    .map(l => l.ischecked)
    .some(v => !!v)
  )
  .map(r => getRequiredResponseObjectProperties(r))
  
console.dir(filter(responsetable))

答案 2 :(得分:0)

一种非常简洁的方法是使用_.map/_.mapValues/_.filter

_.map(data, (x) => _.mapValues(x, (y) => _.isArray(y) ? _.filter(y, (k) => k.ischecked === true) : y))

包含数据的完整代码:

var data = [{
  "Qty": 3,
  "List1": [],
  "List2": [{
      "serialNumber": "1",
      "ischecked": false
    },
    {
      "serialNumber": "2",
      "ischecked": true
    },
    {
      "serialNumber": "3",
      "ischecked": false
    }
  ],
  "lineItemId": 50,
  "lineItemQty": 3,
}]

var result = _.map(data, (x) => _.mapValues(x, (y) => _.isArray(y) ? _.filter(y, (k) => k.ischecked === true) : y))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>