Как использовать Array.protoype.map () для массива объектов, чтобы отфильтровать некоторые конкретные ключи на основе его значений? - PullRequest
3 голосов
/ 27 мая 2019

У меня есть следующий массив объектов, в котором некоторые конкретные ключи имеют значение, которое является либо строкой, либо массивом.Я хочу получить ключи со строковыми значениями как есть и удалить «NA» из ключей со значениями массива.

Я пытаюсь добиться того же самого, используя метод .map для массива, проверьте типзначение каждого ключа в объекте данных, если массив затем использует .filter для удаления значений «NA».

var dataArr = [
    {
     a: 'foo',
     b: [1, 2, "NA", "NA", 3],
     c: ["NA", 6]
    },
    {
     a: 'bar',
     b: ["NA", "NA", "NA"],
     c: []
    }
];
dataArr.map(dataObj => {
    for (let key in dataObj) {
        if (key !== 'a')
            dataObj[key] = dataObj[key].filter(val => { if(val != "NA") return val})
    }
    return dataObj;
});

Приведенный выше блок кода работает, как и ожидалось, но я хочу лучше и на будущеерешение.Более того, это тоже выглядит плохо.

Ответы [ 5 ]

3 голосов
/ 27 мая 2019

Вы можете сделать это, используя вложенные map() и filter()

  • Прежде всего используйте map() в основном массиве.
  • Затем получите записи каждого объекта, используя Object.entries()
  • Затем используйте map() для записей каждого объекта.
  • Возвращает значение как есть, если Array.isArray равно false, в противном случае возвращает отфильтрованное значение массива.
  • Наконец, используйте Object.fromEntries() для создания объекта.

var dataArr = [
    {
     a: 'foo',
     b: [1, 2, "NA", "NA", 3],
     c: ["NA", 6]
    },
    {
     a: 'bar',
     b: ["NA", "NA", "NA"],
     c: []
    }
];

const res = dataArr.map(x => 
               Object.fromEntries(
                   Object.entries(x)
                     .map(([k,v]) => 
                        [k,Array.isArray(v) ? v.filter(b => b !== "NA") : v])
                     )
               )

console.log(res)
3 голосов
/ 27 мая 2019

Если вы просто хотите обновить исходный массив, вы можете перебрать массив, используя forEach.Затем переберите ключи каждого объекта с помощью for...in и проверьте, является ли он массивом с использованием Array.isArray().Обновите свойство после фильтрации из значения NA

const dataArr = [{a:'foo',b:[1,2,"NA","NA",3],c:["NA",6]},{a:'bar',b:["NA","NA","NA"],c:[]}];

dataArr.forEach(o => {
  for (const key in o) {
    if (Array.isArray(o[key]))
      o[key] = o[key].filter(s => s !== "NA")
  }
})

console.log(dataArr)

Если вы хотите получить новый массив без изменения исходных объектов, вы можете использовать map, например:

const dataArr = [{a:'foo',b:[1,2,"NA","NA",3],c:["NA",6]},{a:'bar',b:["NA","NA","NA"],c:[]}];

const newArray = dataArr.map(o => {
  const newObj = {};
  
  for (const key in o) {
    if (Array.isArray(o[key]))
      newObj[key] = o[key].filter(s => s !== "NA")
    else
      newObj[key] = o[key]
  }
  
  return newObj;
})

console.log(newArray)
1 голос
/ 27 мая 2019

Используйте for...of в записях объекта. Для каждой записи проверьте, является ли это массивом. Если это фильтр массива, а затем назначить новый объект. Если нет, назначьте без фильтрации. Это не приведет к изменению исходного массива.

const dataArr = [{"a":"foo","b":[1,2,"NA","NA",3],"c":["NA",6]},{"a":"bar","b":["NA","NA","NA"],"c":[]}]

const result = dataArr.map(dataObj => {
  const filterObject = {};
  
  for (const [key, val] of Object.entries(dataObj)) {
    filterObject[key] = Array.isArray(val) ?
      dataObj[key].filter(val => val != 'NA')
      :
      val;
  }
  
  return filterObject;
});

console.log(result);
0 голосов
/ 27 мая 2019

Я думаю, это будет лучший рефакторинг кода, пожалуйста, предоставьте желаемый результат:

dataArr.forEach(object=>{
  for (let value in object){
   let isArr = Object.prototype.toString.call(data) == '[object Array]';
   isArr? object[value] = object[value].filter(val => {return val != "NA"}):null}
 })
0 голосов
/ 27 мая 2019

    const dataArr = [{
            a: 'foo',
            b: [1, 2, "NA", "NA", 3],
            c: ["NA", 6]
        },
        {
            a: 'bar',
            b: ["NA", "NA", "NA"],
            c: []
        }
    ];

    const res = dataArr.map((obj) => {
        for(let i in obj){
            if(Array.isArray(obj[i])){
                obj[i] = obj[i].filter(el=>el!=="NA")
            }
        }
        return obj;
    });

    console.log('@>res', res)
...