Используйте lodash для создания массива из объекта по имени свойства - PullRequest
0 голосов
/ 27 августа 2018

У меня есть объект, который мне нужно превратить в массив данных на основе определенного ключа.

Вот мой оригинальный объект:

{
  "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 голосов
/ 29 августа 2018

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

0 голосов
/ 29 августа 2018

Если вы ищете какие встроенные функции для выполнения map и filter вместе, то вы всегда можете объединить операции map и filter в одну 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)

Однако я предлагаю вам не изменять и не копировать исходный объект и переопределить blocks на копии, чтобы сделать его новым выводом.

0 голосов
/ 27 августа 2018

После фильтрации blocks вы можете использовать map и concat, чтобы присоединиться к объекту 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>
0 голосов
/ 27 августа 2018

Вы можете связать _.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>
0 голосов
/ 27 августа 2018

Есть ли у 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 });
...