Чтобы извлечь элемент из массива, вы можете сделать следующее:
array.filter(item=>item!==itemToRemove)
Итак, в вашем примере:
this.deleteItem = item => event => {
const filter = getter => val => getter(val) !== item.id
this.setState({
res: this.state.res.filter(filter(({id})=>id)),
selectedItems: this.state.selectedItems.filter(
filter(id=>id)
)
})
}
Проблема в том, что res сохраняет массив объектов с идентификатором (например: [{id:1}]
, затем selectedItems является массивом, в котором хранится идентификатор: (например: [1]).
Array.prototype.filter работает следующим образом: newArray = array.filter(filterFunction)
. Для каждого элемента в массиве функция filterFunction вызывается с этим элементом. Если filterFunction возвращает false
, то этот элемент не копируется в newArray
, он возвращает значение true, если он копируется в newArray. Исходный массив остается неизменным (как это должно быть с состоянием, потому что вы не должны изменять его).
Так что проблема в том, что ваша функция фильтра получает элемент массива, решает, должен ли он возвращать true или false (true, чтобы сохранить элемент и false не сохранять). Так что, если я отфильтрую res
, функция фильтра получит {id:X}
(объект с идентификатором), но когда я отфильтрую selectedItems
, я получу X
( id ) .
Так что фильтр функционирует Однако необходимо удалить элемент (ы) с определенным идентификатором; с res
этот идентификатор является свойством объекта, а с selectedItems
это идентификатор. Для res
вы можете написать функцию получения, чтобы получить идентификатор объекта: resItem=>resItem.id
, присвоить этой функции элемент из res
, и он вернет идентификатор. Для selectedItems
функция получения должна просто возвращать значение, которое она дала, потому что элементы в selectedItems
являются идентификаторами, так что функция получения выглядит как id=>id
Хорошо, давайте вернемся для фильтрации у меня есть массив идентификаторов с именем selectedItems
[9] и я хочу удалить идентификатор со значением 9, давайте назовем этот idToRemove, чтобы я мог сделать: selectedItems.filter(id=>id!==idToRemove)
. Эта же функция не будет работать с res
, потому что {id:9}
никогда не будет равняться 9
.
Но что, если я передам селектор в функцию фильтра, здесь это немного усложняется, потому что функции могут возвращать функция:
const idToRemove = 9;
//filter function return true for array item to stay in the copied array
// and false to not include the array item in the copy
const filter = getter => arrayItem =>
getter(arrayItem) !== idToRemove;
//passing filter a getter function will return a function that takes
// an item and uses the getter function on that item to compare it
// to idToRemove
const compareId = filter(id => id);
console.log('keep 9?', compareId(9));
console.log('keep 8?', compareId(8));
//now create a filter function that takes an object and uses
// the getter to get object.id and compares that to idToRemove
const compareObjectWithId = filter(object => object.id);
console.log('keep {id:9}?', compareObjectWithId({ id: 9 }));
console.log('keep {id:8}?', compareObjectWithId({ id: 8 }));
Итак, compareId
- это функция, которую мы можем использовать для фильтрации элемента из selectedItems
, а compareObjectWithId
- это функция, которую мы можем использовать для фильтрации элемента из res
Вот как используется фильтр:
const idToRemove = 9;
const createFilterFunction = getter => arrayItem =>
getter(arrayItem) !== idToRemove;
console.log(
'[2,9] remove id 9',
[2, 9].filter(createFilterFunction(id => id))
);
console.log(
'[{id:2},{id:9}] remove id 9',
[{ id: 2 }, { id: 9 }].filter(
createFilterFunction(object => object.id)
)
);
Для завершения я добавлю современный код для удаления ключа из объекта (не пытайтесь сделать это во фрагменте кода переполнения стека, поскольку он использует древнюю версию Babel)
const org = {a:1,b:2};
const withoutA = Object.fromEntries(
Object.entries(org).filter(([key])=>key!=='a')//removed key 'a'
)