使用lodash通过属性名称从对象创建数组

时间:2018-08-27 14:54:31

标签: javascript lodash

我有一个对象,需要根据特定的键将其转换为数据数组。

这是我的原始物:

{
  "centerID": "6",
  "marketID": "1",
  "invoiceGroupID": "4",
  "blocks": [
    {
      "name": "Monday-Friday 11:00AM-3:00PM",
      "isChecked": true
    },
    {
      "name": "Monday-Friday 7:00AM-11:00AM",
      "isChecked": false
    },
    {
      "name": "Saturday-Sunday 2:00PM-8:00PM",
      "isChecked": true
    }
  ],
  "bankedHoursYN": "N"
}

当前,我使用filter仅通过blocks向我提供isChecked = true,其中_.filter(this.mappingForm.get('blocks').value, { isChecked: true })

这样的结果使我有了:

{
  "centerID": "6",
  "marketID": "1",
  "invoiceGroupID": "4",
  "blocks": [
    {
      "name": "Monday-Friday 11:00AM-3:00PM",
      "isChecked": true
    },
    {
      "name": "Saturday-Sunday 2:00PM-8:00PM",
      "isChecked": true
    }
  ],
  "bankedHoursYN": "N"
}

这很好,给我留下了两个对象的数组。

我的最终结果是只拥有一个name值的数组。

预期输出:

{
  "centerID": "6",
  "marketID": "1",
  "invoiceGroupID": "4",
  "blocks": ['Monday-Friday 11:00AM-3:00PM','Saturday-Sunday 2:00PM-8:00PM'],
  "bankedHoursYN": "N"
}

lodash是否有内置的方式来处理此问题?

5 个答案:

答案 0 :(得分:1)

您可以将_.filter()_.map()链接起来,用blocks来获得isChecked: true的名称:

const data = { "centerID": "6", "marketID": "1", "invoiceGroupID": "4", "blocks": [ { "name": "Monday-Friday 11:00AM-3:00PM", "isChecked": true }, { "name": "Monday-Friday 7:00AM-11:00AM", "isChecked": false }, { "name": "Saturday-Sunday 2:00PM-8:00PM", "isChecked":true } ], "bankedHoursYN": "N" };

data.blocks = _(data.blocks)
  .filter('isChecked')
  .map('name')
  .value();
  
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

答案 1 :(得分:0)

  

lodash是否有内置的方式来处理此问题?

我不知道,但是Javascript有。

使用Array.prototype.filter()并链接Array.prototype.map()

let obj = {
  "centerID": "6",
  "marketID": "1",
  "invoiceGroupID": "4",
  "blocks": [
    {
      "name": "Monday-Friday 11:00AM-3:00PM",
      "isChecked": true
    },
    {
      "name": "Monday-Friday 7:00AM-11:00AM",
      "isChecked": false
    },
    {
      "name": "Saturday-Sunday 2:00PM-8:00PM",
      "isChecked": true
    }
  ],
  "bankedHoursYN": "N"
}

obj.blocks = obj.blocks.filter(i=>i.isChecked).map(i=>i.name)

console.log(obj)

如果您需要使用ES5:

obj.blocks = obj.blocks
  .filter(function(i) { return i.isChecked })
  .map(function(i) { return i.name });

答案 2 :(得分:0)

过滤blocks后,可以使用mapconcat来加入name对象的block

var data = { "centerID": "6", "marketID": "1", "invoiceGroupID": "4", "blocks": [ { "name": "Monday-Friday 11:00AM-3:00PM", "isChecked": true }, { "name": "Monday-Friday 7:00AM-11:00AM", "isChecked": false }, { "name": "Saturday-Sunday 2:00PM-8:00PM", "isChecked":true } ], "bankedHoursYN": "N" };
data.blocks = _.chain(data.blocks).filter({ isChecked: true }).map(({name}) => name).concat().value();
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

答案 3 :(得分:0)

如果您正在搜索用于执行mapfilter的内置功能,那么您始终可以将mapfilter操作合并到一个{ {1}}(无论是在reduce还是在简单的lodash中)都只能将数组迭代一次。

因此,结构将为:

vanilla JS

因此,在您的情况下: <Array>.reduce((res, each) => (<filter condition> && res.push(<mapped data>), res), [])

obj.blocks.reduce((r, b) => (b.isChecked && r.push(b.name), r), [])

但是,我建议您不要变异并制作原始对象的副本,并覆盖副本上的var obj = { "centerID": "6", "marketID": "1", "invoiceGroupID": "4", "blocks": [ { "name": "Monday-Friday 11:00AM-3:00PM", "isChecked": true }, { "name": "Monday-Friday 7:00AM-11:00AM", "isChecked": false }, { "name": "Saturday-Sunday 2:00PM-8:00PM", "isChecked": true } ], "bankedHoursYN": "N" }; obj.blocks = obj.blocks.reduce((r, b) => (b.isChecked && r.push(b.name), r), []); console.log(obj)以使其成为新的输出。

答案 4 :(得分:0)

var data.blocks = .map( .filter(data.blocks,function(o){return o.isChecked === true;}),'name');