Arthur
Arthur

Reputation: 3506

Remove an object from the array then update the property of all objects

I want to remove an object by id from an array and then update the position property for all objects. For example I have an array like:

const arr = [
  {id: 10, position: 1},
  {id: 11, position: 2},
  {id: 12, position: 3},
  {id: 13, position: 4}
]

Example: First I need to remove the object with id 12 then change the position property for each object. Result:

const arr = [
  {id: 10, position: 1},
  {id: 11, position: 2},
  {id: 13, position: 3}
]

My attempt:

const fn = id => pipe(
  reject(propEq('id', id)),
  map((item, key) => evolve({position: key}))
);

Upvotes: 2

Views: 67

Answers (2)

Ori Drori
Ori Drori

Reputation: 191986

Create a mapIndexed function by applying R.addIndex to R.map. This is needed because R.map doesn't pass the current index to the callback function.

In addition, you'll need to pass a function to R.evolve to set the position (via R.always or an arrow function), and you'll also need to pass the item to evolve:

const { pipe, reject, propEq, addIndex, map, evolve, always } = R;

const mapIndexed = addIndex(map);

const fn = id => pipe(
  reject(propEq('id', id)),
  mapIndexed((item, key) => evolve({ position: always(key + 1) }, item))
);

const arr = [{"id":10,"position":1},{"id":11,"position":2},{"id":12,"position":3},{"id":13,"position":4}];

const result = fn(11)(arr);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

I would skip R.evolve in this case, and use spread on the item to generate the new object, and assign the new position:

const { pipe, reject, propEq, addIndex, map } = R;

const mapIndexed = addIndex(map);

const fn = id => pipe(
  reject(propEq('id', id)),
  mapIndexed((item, key) => ({ ...item, position: key + 1 }))
);

const arr = [{"id":10,"position":1},{"id":11,"position":2},{"id":12,"position":3},{"id":13,"position":4}];

const result = fn(11)(arr);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

Upvotes: 4

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

You can use Array.filter() to remove and Array.map() to re-position the items as following:

const arr = [
  {id: 10, position: 1},
  {id: 11, position: 2},
  {id: 12, position: 3},
  {id: 13, position: 4}
]


repositionedArray = arr.filter(item => item.id != 11).map((item, index) => ({...item, position: index+1}))


console.log(repositionedArray);

Hope this helps

Upvotes: 3

Related Questions