首页 > 解决方案 > 比较两个数组并显示第一个数组中具有第二个数组键的项

问题描述

我有两个不同的数组,一个包含我在列表中使用的所有数据,另一个仅包含来自过滤器的值,我允许用户选择。所以我的第一个数组是这个:

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([]);

我想要做的是在我的钩子上设置第一个数组的对象,这些对象的状态与我的第二个数组(项目)上的一个项目(项目)的值相同,这样我以后可以在上做一个 messageData 的映射我的渲染,在这种情况下,我必须渲染我的消息数组的第一条和第三条记录,因为它们的状态为“已发送”,并且该值在我的 items 数组上。

问题是,我不知道如何比较和获得这些结果,我尝试制作消息数组的映射并过滤作为状态之一的项目数组值,如下所示:

let search = [];
messages
.filter((option) => {
 return(
  option.value.status = items.value
 )
})
.map((option) => {
   search.push(option);
})
   setMessageData(search);

但这不起作用,我不知道如何解决它,任何人都可以帮我解决这个问题吗?

标签: arraysreactjsfiltermapping

解决方案


这是一个很好的情况reduce()

reduce() 方法对数组的每个元素执行一个 reducer 函数(您提供),从而产生单个输出值。

Array.prototype.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)


把它变成一个函数

为了回应您关于接收不同结果的评论,我将其变成了一个函数,可以轻松测试来自不同statusArrays 的结果,并且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"]));


推荐阅读