Невозможно получить весь объект из вложенного объекта json на основе совпадения значения ключа - PullRequest
1 голос
/ 08 мая 2020

У меня есть вложенные данные json. Он содержит некоторые объекты со счетом 0, которые необходимо удалить из JSON. Данные приведены ниже

const data = {
  "name": "A",
  "desc": "a",
  "count": 2,
  "children": [
    {
      "name": "A1",
      "desc": "a1",
      "count": 2,
      "children": [
        {
          "name": "A1-sub1",
          "desc": "a1-sub1",
          "count": 2,
        },
        {
          "name": "A1-sub2",
          "desc": "a1-sub2",
          "count": 0,
        },
      ]
    },
    {
      "name": "A2",
      "desc": "a2",
      "count": 0
    }
  ]
}

Здесь у объекта A1-sub2 и A2 есть счетчик 0, который необходимо удалить. Я попытался удалить весь объект, но он не работал. Мой код выглядит следующим образом:

const deepCopy = (arr) => {
  let copy = [];
  arr.forEach(elem => {
    if(Array.isArray(elem)){
      copy.push(deepCopy(elem))
    }else{
      if (typeof elem === 'object') {
        copy.push(deepCopyObject(elem))
    } else {
        copy.push(elem)
      }
    }
  })
  return copy;
};
const deepCopyObject = (obj) => {
  let tempObj = {};
  for (let [key, value] of Object.entries(obj)) {
      if(key === "count"){
        if(obj[key] === 0){
          Object.keys(obj).forEach(function(key) { 

            delete obj[key]; 
            });
        }
      }
    if (Array.isArray(value)) {
      tempObj[key] = deepCopy(value);
    } else {
      if (typeof value === 'object') {
        tempObj[key] = deepCopyObject(value);
      } else {
        tempObj[key] = value
      }
    }
  }
  return tempObj;
};
console.log(deepCopyObject(data));

Ожидаемый результат должен быть

const result = {
  "name": "A",
  "desc": "a",
  "count": 2,
  "children": [
    {
      "name": "A1",
      "desc": "a1",
      "count": 2,
      "children": [
        {
          "name": "A1-sub1",
          "desc": "a1-sub1",
          "count": 2,
        }
      ]
    }
  ]
}

Ответы [ 3 ]

1 голос
/ 08 мая 2020

Предполагая, что структура имеет c статус и больше не гнездится, это работает.

const data = {
  "name": "A",
  "desc": "a",
  "count": 2,
  "children": [{
      "name": "A1",
      "desc": "a1",
      "count": 2,
      "children": [{
          "name": "A1-sub1",
          "desc": "a1-sub1",
          "count": 2,
        },
        {
          "name": "A1-sub2",
          "desc": "a1-sub2",
          "count": 0,
        },
      ]
    },
    {
      "name": "A2",
      "desc": "a2",
      "count": 0
    }
  ]
};

data.children = data.children.reduce((acc, child) => {
  if (child.count !== 0) {
    if (child.children) {
      child.children = child.children.reduce((nestedAcc, nestedChild) => {
        if (nestedChild.count !== 0) {
          nestedAcc.push(nestedChild);
        }
        return nestedAcc
      })
    }
    acc.push(child);
  }
  return acc
}, []);
console.log(data.children);
1 голос
/ 08 мая 2020

Вместо двух одинаковых функций вы можете сделать это только с помощью одной функции.

Единственная проблема с этой функцией состоит в том, что она меняет порядок ключей объектов. Если они вам не нужны в том же порядке, тогда подойдет эта функция.

const filterObject = (obj) =>
   Object.keys(obj)
  .slice(0)
  .reduce((accumulator, currentKey, _currentIndex, array) => {
    if (obj.count === 0) {
      array.splice(1);
      return null;
    }

    if (currentKey === "children") {
      accumulator.children = [];

      for (let subObj of obj.children) {
        if (!subObj["children"]) {
          if (subObj.count > 0) accumulator.children.push(subObj);
        } else {
          let filtered = filterObject(subObj);
          if (filtered) accumulator.children.push(filtered);
        }
      }
    } else accumulator[currentKey] = obj[currentKey];

    return accumulator;
  }, {});

const data = {
  name: "A",
  desc: "a",
  count: 2,
  children: [{
      name: "A1",
      desc: "a1",
      count: 2,
      children: [{
          name: "A1-sub1",
          desc: "a1-sub1",
          count: 2,
        },
        {
          name: "A1-sub2",
          desc: "a1-sub2",
          count: 0,
        },
      ],
    },
    {
      name: "A2",
      desc: "a2",
      count: 0,
    },
  ],
};

console.log(filterObject(data));
0 голосов
/ 08 мая 2020

потому что вы удаляете из obj, а не из tempObj, который вы возвращаете

 if(obj[key] === 0){
      Object.keys(obj).forEach(function(key) { 

        delete obj[key]; 
        });

Следующий код работает для меня

 const deepCopy = (arr) => {
let copy = [];
arr.forEach(elem => {
  if(Array.isArray(elem)){
    copy.push(deepCopy(elem))
  }else{
    if (typeof elem === 'object') {
      copy.push(deepCopyObject(elem))
  } else {
      copy.push(elem)
    }
  }
})
return copy;
};

   const deepCopyObject = (obj) => {
let tempObj = {};
for (let [key, value] of Object.entries(obj)) {
    if(key === "count"){
      if(obj[key] === 0){
        tempObj = null;
      }
    }
  if (Array.isArray(value)) {
    tempObj[key] = deepCopy(value);
  } else {
    if (typeof value === 'object') {
      tempObj[key] = deepCopyObject(value);
    } else if(tempObj != null) {
      tempObj[key] = value
    }
  }
}
return tempObj;
};

const noNull = (v) => {
  if (v && typeof v === 'object' && Array.isArray(v.children)) v.children = 
 v.children.filter(noNull);
  return v !== null;
 };


const input = require('./input');
const data = [deepCopyObject(input)];

console.log(JSON.stringify(data.filter(noNull)));

ввод - это данные, которые вы предоставили

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...