Home > Net >  Remove object value in array if it doesn't exist
Remove object value in array if it doesn't exist

Time:03-08

I have an array of objects as follows

const array = [ 
{id:1,parentIds:[]}
{id:2,parentIds:[1,3]}
{id:3,parentIds:[1,2,4]}
]

How can I make it possible to remove an object's parentIds value if it doesn't exist in the array? to look something like this

const array = [ 
{id:1,parentIds:[]}
{id:2,parentIds:[1,3]}
{id:3,parentIds:[1,2]}
]

CodePudding user response:

You can try this solution:

const array = [{
    id: 1,
    parentIds: []
}, {
    id: 2,
    parentIds: [1, 3]
}, {
    id: 3,
    parentIds: [1, 2, 4]
}];

const idsArr = array.map(el => el.id);

array.forEach(el => {
    el.parentIds = el.parentIds.filter(el => idsArr.includes(el));
})
    
console.log(array);

CodePudding user response:

It's better to avoid mutating the original array parentIds, use immutation to create new array:

const array = [ 
{id:1,parentIds:[]},
{id:2,parentIds:[1,3]},
{id:3,parentIds:[1,2,4]}
]

const ids = array.map(({id}) => id)

const newArray = array.map(({parentIds,...arrayItemRest}) => {
  const newparentIds = parentIds.filter(id => ids.includes(id))
  
  return {
    ...arrayItemRest,
    parentIds: newparentIds
  }
})

CodePudding user response:

const array = [ 
{id:1,parentIds:[]},
{id:2,parentIds:[1,3]},
{id:3,parentIds:[1,2,4]}
]

// Let's create an array only containing the ids
var ids = array.map(o => o.id)

// Loop array
array.forEach((object) => {
  // Loop all parent ids
  object.parentIds.forEach((id, index) => {
    // Check if we find the id in our list
    if (ids.indexOf(id) === -1) {
      // Delete item from array if not found
      object.parentIds.splice(index, 1)
    }
  })
})

// The result
console.log(array)

CodePudding user response:

You can map (documentation here) your parent Ids and then filter using the includes method (documentation here)

const array = [{
    id: 1,
    parentIds: []
  },
  {
    id: 2,
    parentIds: [1, 3]
  },
  {
    id: 3,
    parentIds: [1, 2, 4]
  }
]

const parents = array.map(x => x.id)

array.forEach(item => {
  item.parentIds = item.parentIds.filter(x => parents.includes(x))
})

console.log(array)

CodePudding user response:

Loop through inner parentIds array and remove members that are not any of the outer ids.

const array = [
  { id: 1, parentIds: [] },
  { id: 2, parentIds: [1, 3] },
  { id: 3, parentIds: [1, 2, 4] }
];

array.forEach(
  (o) =>
    (o.parentIds = o.parentIds.filter((pI) =>
      array.map((o) => o.id).includes(pI)
    ))
);

console.log(array);

CodePudding user response:

Get a list of keys/ids using map, and then map over the array of objects to filter out the parentIds that are missing, returning a new array of updated objects.

const data=[{id:1,parentIds:[]},{id:2,parentIds:[1,3]},{id:3,parentIds:[1,2,4]}];

function removeIds(data) {
  
  // Get the ids from all the array objects
  const keys = data.map(obj => obj.id);
  
  // `map` over the array and return a new
  // array of updated objects
  return data.map(obj => {
  
    const newIds = obj.parentIds.filter(id => {
      return keys.includes(id);
    });

    return { ...obj, parentIds: newIds };
  
  });

}

console.log(removeIds(data));

CodePudding user response:

Well basic way would be to go trough array every time there is a change, and update parentIds list.

To do that:

  const dummyArray = [
    {id:1,parentIds:[]},
    {id:2,parentIds:[1,3]},
    {id:3,parentIds:[1,2,4]}
  ];
  /* You can do this with regular array, this only ensures that ids are unique */
  const idsSet = new Set();

  dummyArray.forEach(it =>  idsSet.add(it.id));
  dummyArray.forEach(it => {
      /* If you are using array, you would need to loop trough for each id and check if existing */
      const newParentIds = it.parentIds.filter(id => idsSet.has(id));
      it.parentIds = newParentIds;
      console.log(it.parentIds);
  });

There would be a better solution for this for sure, so please try to take this as an example for logic which can be used.

CodePudding user response:

From the above comments ...

As long as one does not know, what actually describes a reliable parent-child description one can not solve the task. Thus if one assumes the above being such a stable description one has to work oneself from the first to the last item, collecting with each step all the already processed id values and then, within each currently processed parentIds array, one has to remove any id value which is not part of the current id-collection.

A reduce based approach can achieves both, implementing the performant lookup and not altering/mutating the original data structure ...

const array = [ 
  { id:1, parentIds: [] },
  { id:2, parentIds: [1,3] },
  { id:3, parentIds: [1,2,4] },
];

const sanitizedArray = array
  .reduce(({ lookup, result }, { id, parentIds, ...rest }) => {

    lookup[id] = true;
    result.push({
      id,
      parentIds: parentIds.filter(parentId => !!lookup[parentId]),
      ...rest,
    });
    return { lookup, result };

  }, { lookup: {}, result: [] }).result;

console.log({
  array,
  sanitizedArray,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

CodePudding user response:

const array = [
  { id: 1, parentIds: [] },
  { id: 2, parentIds: [1, 3] },
  { id: 3, parentIds: [1, 2, 4] },
];
const removeParentIds = (array) => {
  return array.map((item) => {
    const { parentIds } = item;
    return {
      ...item,
      parentIds: parentIds.filter((parentId) => array.some((item) => item.id === parentId)),
    };
  });
}
console.log(removeParentIds(array));

CodePudding user response:

You can add childIds in each object, so when you remove one object you can go through each of child's and remove from it's parents as-well.

const array = [ 
    {id:1,parentIds:[],childIds:[2,3]},
    {id:2,parentIds:[1,3],childIds:[3]},
    {id:3,parentIds:[1,2],childIds:[2]}
]


function idChecker(id){
    for(let i=0; i<array.length;i  ) if(array[i].id === id) return i;
    return undefined
}


function removeObject(id){
    let key = idChecker(id)
    if(key === undefined) return false
    let children = array[key].childIds
    children.map(val => {
        let keyOfVal = idChecker(val)
        array[keyOfVal].parentIds.splice(array[keyOfVal].parentIds.indexOf(id), 1)
    })
    array.splice(idChecker(id), 1)
    return true
}
  • Related