【问题标题】:How to prevent duplicate data from for loop如何防止for循环重复数据
【发布时间】:2021-03-19 20:03:14
【问题描述】:

我想知道防止重复数据进入新数组的最佳方法是什么。我有一个服务调用,它返回相同的数组 3 次。我正在尝试从数组中的对象内部获取一个数字并将它们相加以创建一个“总”数(fullRentAmt),但是由于该数组被返回了 3 次,所以我得到了总数 *3。我在想也许 .some() 或 .filter() 可以在这里使用,但我从未使用过这些/不确定如何在这里实现。感谢您的帮助!

我试过了,但它不起作用/新数组没有被填充:

组件


    properties = [];
    fullRentAmt: number = 0;

            const propertyDataSub = this.mainService.requestPropertyData()
              .subscribe((pData: PropertyData[]) => {
                if (pData) {
                  const propertyData = pData;
                  for (let i = 0; i < propertyData.length; i++) {
                    if (this.properties[i].propertyId !== propertyData[i].propertyId) {
                      this.properties.push(propertyData[i]);
                    }
                  }
                  for (let i = 0; i < this.properties.length; i++) {
                    this.fullRentAmt += this.properties[i].tenancyInformation[0].rentAmount;
                  }
              });

从后端返回的数据(2 个对象的数组):


[
   {
      "tenantsData":[
         {
            "email":null,
            "tenantNames":null,
            "propertyId":2481,
         }
      ],
      "tenancyInformation":[
         {
            "id":2487,
            "rentAmount":1000,
         }

      ],
   },
   {
      "tenantsData":[
         {
            "email":null,
            "tenantNames":null,
            "propertyId":3271,
         }
      ],
      "tenancyInformation":[
         {
            "id":3277,
            "rentAmount":1200,
         }

      ],
   },

【问题讨论】:

  • 但是为什么后端会返回 3 次呢?这是来自 Angular 的 3 次请求吗?还是来自后端的错误?

标签: javascript json angular


【解决方案1】:

我不是 Angular 开发者,但希望我的回答对你有所帮助。

让 for 循环尽可能多地复制数据。你只需要改变将东西从数组存储到JavaScript Set的想法

基本上,它与数组非常相似,它们是与数组非常相似的列表和可迭代对象,唯一的区别是它们不允许重复,

用法:

const properties = new Set()
properties.add("yellow")
properties.add("blue")
properties.add("orange")
console.log(properties) // yellow, blue, orange

properties.add("blue") 
properties.add("blue") 
properties.add("blue") 
console.log(properties) // yellow, blue, orange

在你的for循环结束后,你可能想把这个集合转换成一个普通的数组,你所要做的就是使用解构:

const propertiesArray = [...properties]

【讨论】:

    【解决方案2】:

    @YaYa 是正确的。我添加了这个以在 Angular 中显示正确的代码

    properties = [];
    fullRentAmt: number = 0;
    
    const propertyDataSub = this.mainService.requestPropertyData()
      .subscribe((pData: PropertyData[]) => {
        if (pData && pData.length) {
          let arrSet = new Set()
          const propertyData = pData;
          for (let i = 0; i < propertyData.length; i++) {
            if (this.properties[i].propertyId !== propertyData[i].propertyId) {
              arrSet.add(propertyData[i])
            }
          }
          this.properties = Array.from(arrSet);
    
          for (let i = 0; i < this.properties.length; i++) {
            this.fullRentAmt += this.properties[i].tenancyInformation[0].rentAmount;
          }
      });
    

    【讨论】:

      【解决方案3】:

      您需要做的第一件事是修复您的服务器并返回一次列表。

      如果服务器超出您的范围,您可以在前端结合使用distinctUntilChanged 管道和isEqual 方法。您可以自己实现它,也可以使用 lodash 等库。

      另外,您不必订阅,在模板中使用async 管道。

      this.properties$ = this.mainService.requestPropertyData()
        .pipe(
          distinctUntilChanged(isEqual) // provide isEqual function somehow
        );
      this.totalRentAmount$ = properties$.pipe(
        map(getTotalRentAmount)
      );
      
      // maybe in some other utility file:
      export const getTotalRentAmount = (properties: Property[]): number => {
        return properties
          .map(property => property.tenancyInformation.rentAmount)
          .reduce((total, amount) => total + amount, 0);
      }
      

      然后在模板中:

      <div>Total Rent Amount: {{ totalRentAmount | async }}</div>
      

      另外,如果你真的需要订阅组件并且只对 observable 的第一个发射值感兴趣,你可以使用first() 或take(1) 管道在第一个值后自动取消订阅。

      this.mainService.requestPropertyData()
        .pipe(
          first() // or take(1)
        )
        .subscribe(properties => this.properties = properties);
      
      

      See the difference between first() and take(1)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 2016-01-16
        • 2023-04-03
        相关资源
        最近更新 更多