通过两个数组反应映射而不重复

Posted

技术标签:

【中文标题】通过两个数组反应映射而不重复【英文标题】:React map through two arrays without duplication 【发布时间】:2019-12-12 15:41:09 【问题描述】:

我有一个问题,我必须制作一开始分成两半的表格,显示左侧和中间的 Id,然后在收到来自 api 请求的数据后,比较这两个数组并将差异标记为红色。实际上它部分工作得很好,所以它映射到 2 个数组,如果它发现任何差异,然后将其涂成红色,问题是它也复制了所有元素,并且在最终表格中多次出现相同的行。我知道这是因为我在另一个映射中映射数组,但我不知道如何解决这个问题。基本思想是:显示所有结果,不重复,并标记差异。我知道如何标记差异,但完全不知道如何不显示重复这里我发布了最小化的代码以便于阅读谢谢!

   const applicationsTable = (classes, current, compared) =>
  current.configuration.applications.map((el, i) => 
      compared &&
      compared.configuration.applications.map((comparedEl, i) => (

        <TableRow key=i>
          <StyledFiledTableCell>
            <Typography variant="body2">
            el.version

            </Typography>
          </StyledFiledTableCell>

          <StyledFiledTableCell colSpan="5">
            <Typography variant="body2">el.aid</Typography>
          </StyledFiledTableCell>

          el.aid == comparedEl.aid ? (
            <>
              <StyledFiledTableCell>
                <Typography variant="body2">
                comparedEl.version

                </Typography>
              </StyledFiledTableCell>

            </>
          ) : (
            <StyledFiledTableCell colSpan="5" />
          )
        </TableRow>
      ))
    ) 

在这里我还发布了我的问题的照片,如您所见,表格中的元素是重复的

这里是我比较和当前数据的示例:

const current.configuration.applications = [
    
      aid: "E82B0601040181C31F0201",
      lifeCycle: "SELECTABLE",
      version: null
    ,
    
      aid: "E82B0601040181C31F027F0301",
      lifeCycle: "SELECTABLE",
      version: null
    ,
    
      aid: "D2760001725041636301",
      lifeCycle: "SELECTABLE",
      version: null
    ,
    
      aid: "D276000172536F434D01",
      lifeCycle: "SELECTABLE",
      version: null
    ,
  ]

  const compared.configuration.applications = [
    
      aid: "E82B0601040181C31F0201",
      lifeCycle: "SELECTABLE",
      version: "03.02"
    ,
    
      aid: "D276000172536F434D01",
      lifeCycle: "SELECTABLE",
      version: "02.07"
    ,
  ]

【问题讨论】:

你可以试试lodash uniq方法 嗯,你能举个例子吗?因为我有点不知道如何在我的情况下实现 lodash 嗯我不太明白你上面的算法。您是否尝试根据aid 值找出两个数组之间的差异,并将它们显示在表格上? 我的问题是,我有两个数组,我从两个不同的 api 响应中获得。第一个命名为 current,另一个命名为 compare。我希望循环并将它们显示在如上所示的表格中。长号是辅助,左边我想显示当前版本,右边我想显示比较的版本。 (如果它为空,那么我不显示它)无论如何你可以在双循环后看到,带辅助的行被重复,我希望摆脱任何重复的行 啊。所以你想将version 从另一个数组映射到左数组?让我重新表述一下您的意图:您想在表格左侧显示current 列表,并在右侧从compared 列表中找到version 值,对吗? 【参考方案1】:

如果我正确理解您的要求,您希望在 compared 列表中显示相同应用程序 ID 的 version 值。如果我是对的,那么你实际上不需要两个.map() 函数,你需要的是一个.find() 方法:

const applicationsTable = (classes, current, compared) =>
  current.configuration.applications.map((el, i) => 
    const comparedEl = compared.configuration.applications.find(comparedEl => comparedEl.aid === el.aid);
    return (
      <TableRow key=i>
        <StyledFiledTableCell>
          <Typography variant="body2">
            el.version
          </Typography>
        </StyledFiledTableCell>

        <StyledFiledTableCell colSpan="5">
          <Typography variant="body2">
            el.aid
          </Typography>
        </StyledFiledTableCell>

        
          comparedEl ? (
          <>
            <StyledFiledTableCell>
              <Typography variant="body2">
                comparedEl.version
              </Typography>
            </StyledFiledTableCell>
          </>
          ) : (
          <StyledFiledTableCell colSpan="5" />
          )
        
      </TableRow>
    );
  
)

【讨论】:

感谢我的朋友的所有帮助:) 确实正确使用 find() 是一个关键。谢谢大家的帮助:) @Jacki 很高兴您找到了解决方案!不用担心! (y)【参考方案2】:

我不确定我是否完全理解您的问题。但如果您有这样的输入数据

const current =  configuration:  ;
current.configuration.applications = [
    
        aid: "1",
        lifeCycle: "SELECTABLE",
        version: null
    ,
    
        aid: "2",
        lifeCycle: "SELECTABLE",
        version: null
    ,
    
        aid: "3",
        lifeCycle: "SELECTABLE",
        version: null
    ,
    
        aid: "4",
        lifeCycle: "SELECTABLE",
        version: null
    ,
];

const compared =  configuration:  ;
compared.configuration.applications = [
    
        aid: "1",
        lifeCycle: "SELECTABLE",
        version: "03.02"
    ,
    
        aid: "4",
        lifeCycle: "SELECTABLE",
        version: "02.07"
    ,
];

通过使用此代码,您将获得当前和比较的唯一值 + 重复值将被合并并由colorRed: true 标记

const merged = current.configuration.applications.map((item, index) => 
    if (compared) 
        const findCompared = compared.configuration.applications.find((e) => e.aid === item.aid, index);
        if (typeof findCompared !== "undefined") 
            return 
                ...item, ...findCompared, colorRed: true
            ;
        
    
    return item;
);

那么结果数组会是这样的:

// merged =>
[
  
    "aid": "1",
    "lifeCycle": "SELECTABLE",
    "version": "03.02",
    "colorRed": true
  ,
  
    "aid": "2",
    "lifeCycle": "SELECTABLE",
    "version": null
  ,
  
    "aid": "3",
    "lifeCycle": "SELECTABLE",
    "version": null
  ,
  
    "aid": "4",
    "lifeCycle": "SELECTABLE",
    "version": "02.07",
    "colorRed": true
  
]

所以您只需通过.map() 浏览merged 并显示所有数据。

P.S.:我更改了“aid”以使示例更简单,但您可以将它与您的数据一起使用。

【讨论】:

它有效!这不是我的意思,但你的解决方案让我想到了,现在它工作正常!非常感谢您的帮助【参考方案3】:

我认为您应该使用另一种方法,而不是在外循环中使用另一个 map()。 尝试使用 Array.prototype.find() 并给 map() 一个条件,如果你能找到一个 dup。

【讨论】:

但问题是有时辅助数据与当前数据和比较数据相同,只需替换其他值,有时在比较数据中是当前不包含的辅助数据,然后必须添加它,所以找到可能不起作用 大声笑我应该对此更清楚。但是 find() 方法工作正常吗? 是的,只是我不知道如何实现它,但你的想法很好!谢谢大佬

以上是关于通过两个数组反应映射而不重复的主要内容,如果未能解决你的问题,请参考以下文章

合并两个数组而不覆盖[重复]

检查两个数组是不是包含相同的对象 - 反应 componentDidUpdate [重复]

将多个数组合并为一个数组而不重复[重复]

检查两个数组之间的相等性[重复]

python - 重复numpy数组而不复制数据

如何从特定索引映射然后在特定索引之后停止[重复]