Удалить основной массив, когда вложенный массив пуст - PullRequest
1 голос
/ 01 февраля 2020

Я получил следующий массив:

var arr = [{
    "mainId": 1,
    "parents": [{
        "parent": 1
      },
      {
        "parent": 2
      }
    ]
  },
  {
    "mainId": 2,
    "parents": [{
      "parent": 3
    }]
  }
]

Я использую эту функцию для удаления указанного c родителя в массиве родителей

var idToDelete = 2
arr.forEach(function (o) {
  o.parents = o.parents.filter(s => s.id !== idToDelete 
})

Это работает нормально. Но когда idToDelete = 3 я хочу удалить весь основной элемент и запустить функцию "startSomething"

, чтобы у меня остался следующий вывод

var arr = [{
  "mainId": 1,
  "parents": [{
      "parent": 1
    },
    {
      "parent": 2
    }
  ]
}]

Как это можно реализовать

Ответы [ 4 ]

1 голос
/ 01 февраля 2020

Вы можете отобразить и затем отфильтровать массив верхнего уровня, вот пример:

var arr = [{
    "mainId": 1,
    "parents": [{
        "parent": 1
      },
      {
        "parent": 2
      }
    ]
  },
  {
    "mainId": 2,
    "parents": [{
      "parent": 3
    }]
  }
];

var idToDelete = 3;

arr = arr.map((v) => ({
    ...v,
    parents: v.parents.filter(({
      parent
    }) => parent !== idToDelete)
  }))
  .filter((v) => v.parents.length);

console.log(arr);
0 голосов
/ 01 февраля 2020

Вот альтернативный метод с функцией, которая использует findIndex для поиска объекта в массиве.

Затем склеивает объект, если у него только 1 родитель.
Или склеивает родителя из объекта, если у него более 1 родителя.

Пример фрагмента:

const deleteParent = (arr, id) =>
{
     let idx = arr.findIndex(x=>x.parents.some(p=> p.parent === id));
     if (idx >= 0 && arr[idx].parents.length === 1 ) {
       let obj = arr[idx];
       // remove object from array and do something
       arr.splice(idx, 1); 
       doSomething(obj);
     }
     else if(idx >= 0){
       let obj = arr[idx];
       let parentIdx = obj.parents.findIndex(x=>x.parent==id);
       // remove parent
       obj.parents.splice( parentIdx, 1);
    }
}

function doSomething (obj) { console.log(`Deleted mainId ${obj.mainId}`) }

var arr = [
  {
    "mainId": 1,
    "parents": [
      {
        "parent": 1
      },
      {
        "parent": 2
      }
    ]
  },
  {
    "mainId": 2,
    "parents": [
      {
        "parent": 3
      }
    ]
  }
];

deleteParent(arr, 3);
console.log(JSON.stringify(arr));

deleteParent(arr, 2);
console.log(JSON.stringify(arr));
0 голосов
/ 01 февраля 2020

Вы можете использовать .filter() для самого массива (для удаления основного объекта) с помощью .some() для возврата true или false в зависимости от того, должен ли он быть удален:

const arr = [{ "mainId": 1, "parents": [{ "parent": 1 }, { "parent": 2 } ] }, { "mainId": 2, "parents": [{ "parent": 3 }] } ];

const removeObj = (arr, id, cb) => {
  const res = arr.filter(({parents}) => !parents.some(({parent}) => parent === id));
  const item_removed = res.length !== arr.length;
  return (item_removed && cb(res), item_removed);
}
 
const startSomething = new_arr => console.log("Starting with arr", new_arr);
removeObj(arr, 3, startSomething);
.as-console-wrapper { max-height: 100% !important;} /* ignore */
0 голосов
/ 01 февраля 2020

Фильтрация родительского массива по наличию .length после изменения дочерних элементов. Также убедитесь, что вы используете свойство .parent (ваши объекты не имеют свойства .id):

const startSomething = () => console.log('startSomething');

var arr = 
[
  {
    "mainId": 1,
    "parents": [
      {
        "parent": 1
      },
      {
        "parent": 2
      }
    ]
  },
  {
    "mainId": 2,
    "parents": [
      {
        "parent": 3
      }
    ]
  }
];

var idToDelete = 3;
arr.forEach(function (o) {
  o.parents = o.parents.filter(s => s.parent !== idToDelete)
});
const newArr = arr.filter(({ parents }) => parents.length);
console.log(newArr);
if (newArr.length !== arr.length) {
  startSomething();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...