#arrays #reactjs #filter #mapping
#массивы #reactjs #Фильтр #сопоставление
Вопрос:
У меня есть два разных массива, один из которых содержит все данные, которые я использую в списке, а другой, который содержит только значения из фильтра, который я разрешаю пользователю выбирать. Итак, мой первый массив — это этот:
messages=[
{id:1, description:'abc', status:'SENT'},
{id:2, description:'hello', status:'CANCELED'},
{id:1, description:'bye', status:'SENT'}];
И мой второй массив — это этот:
items = ["SENT", "CLOSED", "RECEIVED"];
У меня есть этот хук для установки данных, которые прямо сейчас имеют все это:
const [messageData, setMessageData] = useState([]);
И что я пытаюсь сделать, это установить на моем крючке объекты первого массива, которые имеют в качестве статуса то же значение, что и один из элементов в моем втором массиве (items), чтобы я мог позже создать карту MessageData при моем рендеринге, в этом случае я должен отобразить объекты первого массива.первая и третья записи моего массива сообщений, потому что они имеют статус «ОТПРАВЛЕНО», и это значение находится в моем массиве элементов.
Дело в том, что я не знаю, как сравнивать и получать эти результаты, я попытался выполнить сопоставление массива сообщений и отфильтровать элементы, которые имели в качестве состояния одно из значений массива элементов, например:
let search = [];
messages
.filter((option) => {
return(
option.value.status = items.value
)
})
.map((option) => {
search.push(option);
})
setMessageData(search);
Но это не работает, и я не уверен, как это решить, кто-нибудь может мне помочь с этим?
Комментарии:
1. У ваших
messages
элементов нетvalue
свойства, толькоstatus
свойство2. Также вы используете
=
для сравнения, используйте==
3. Я использовал == , но, возможно, я удалил по ошибке, когда вставлял свой код, и да, items.value был неправильным, спасибо!
Ответ №1:
Это хорошая ситуация для reduce()
Метод reduce() выполняет функцию редуктора (которую вы предоставляете) для каждого элемента массива, в результате чего получается одно выходное значение.
Вызов reduce()
массива items выполняет итерацию по каждому элементу и накапливает результаты переданной логики.
В приведенном ниже примере накопитель acc
инициализируется как пустой массив путем передачи []
в качестве второго аргумента в reduce()
вызове.
const messages=[
{id:1, description:'abc', status:'SENT'},
{id:2, description:'hello', status:'CANCELED'},
{id:1, description:'bye', status:'SENT'}];
const items = ["SENT", "CLOSED", "RECEIVED"];
// iterate over each 'status' in the items array
let search = items.reduce((acc, status) => {
// retrieve objects from the messages array that match
const matches = messages.filter(message => message.status === status);
if (matches.length > 0) {
// if matches were found concat the returned array with the accumulator
acc = acc.concat(matches);
}
// return the accumulator to be used in the next iteration
return acc;
}, []);
console.log(search)
Превратить его в функцию
В ответ на ваш комментарий о получении разных результатов я превратил его в функцию, позволяющую легко проверять результаты из разных statusArray
s, и reduce()
вызов работает, как ожидалось.
const messages=[
{id:1, description:'abc', status:'SENT'},
{id:2, description:'hello', status:'CANCELED'},
{id:1, description:'bye', status:'RECEIVED'},
{id:1, description:'xyz', status:'SENT'},
{id:2, description:'hi', status:'SENT'},
{id:1, description:'bye again', status:'RECEIVED'}];
function filterMessagesByStatus(statusArray) {
if (!Array.isArray(statusArray)) return;
return statusArray.reduce((acc, status) => {
const matches = messages.filter(message => message.status === status);
if (matches.length > 0) {
acc = acc.concat(matches);
}
return acc;
}, []);
}
console.log(filterMessagesByStatus(["SENT", "CANCELED", "RECEIVED"]));
console.log(filterMessagesByStatus(["SENT"]));
console.log(filterMessagesByStatus(["CANCELED", "RECEIVED"]));
console.log(filterMessagesByStatus(["SENT", "CANCELED", "RECEIVED"]));
Комментарии:
1. Это сработало отлично! большое спасибо за исправления, а также за объяснение каждого шага
2. Однако у меня есть вопрос, потому что, когда я ищу элементы со статусом «ОТПРАВИТЬ», он показывает мне два объекта, затем я ищу «ОТМЕНЕНО» и ничего не показывает, и если я вернусь и снова выберу «ОТПРАВИТЬ», он продолжает показывать мне 0 результатов. Как я могу предотвратить это?
3. Обновил мой ответ, чтобы протестировать разные поисковые массивы, и он работает так, как ожидалось. Я могу только догадываться, что, возможно, вы искали «ОТПРАВИТЬ» вместо «ОТПРАВЛЕНО». Также
filter
чувствителен к регистру.