【问题标题】:Remove duplicate names in a column删除列中的重复名称
【发布时间】:2026-02-12 10:40:02
【问题描述】:

在我的 Angular 6 应用程序中,我正在制作一个表格,其中包含来自 products 数组的内容,例如,

Ts:

  products: any = {
    "productOne": [
      {
        "id": 1, "product_name": "Product One",
        "productOneProperties": [
          { "id": 1, "property_name": "Length", "property_value": "12cm" },
          { "id": 2, "property_name": "Width", "property_value": "10cm" },
          { "id": 3, "property_name": "Height", "property_value": "20cm" },
        ]
      }
    ],

    "productTwo": [
      {
        "id": 2, "product_name": "Product Two",
        "productTwoProperties": [
          { "id": 1, "property_name": "Length", "property_value": "15cm" },
          { "id": 2, "property_name": "Width", "property_value": "12cm" },
          { "id": 2, "property_name": "Size", "property_value": "Medium" }
        ]
      }
    ]
  }

HTML:

<table>
    <thead>
        <tr>
            <th>
                Property Details &nbsp; &nbsp; &nbsp; &nbsp;
            </th>
            <th>
                {{productOneDetails}}  &nbsp; &nbsp; &nbsp; &nbsp;
            </th>
            <th>
                {{productTwoDetails}} 
            </th>
        </tr> <br>
    </thead>
    <tbody>
        <tr *ngFor="let item of mergedArray">
      <td> {{ item.property_name }} </td>
      <td> {{ item.type === "one" ? item.property_value: '-' }} </td>
      <td> {{ item.type === "two" ? item.property_value: '-'  }} </td>
        </tr>
    </tbody>
</table>

这里我有两个单独的产品和属性,其中属性名称(例如LengthWidth)对于具有不同值的两种产品重复..

工作堆栈闪电战: https://stackblitz.com/edit/angular-9yzwss

当前结果:

Property Details            Product One         Product Two

Length                      12cm                -
Width                       10cm                -
Height                      20cm                -
Length                      -                   15cm
Width                       -                   12cm
Size                        -                   Medium

预期结果:

Property Details            Product One         Product Two

Length                      12cm                15cm
Width                       10cm                12cm
Height                      20cm                -
Size                        -                   Medium

请帮助我通过将重复的属性名称显示为唯一并显示相邻的值来实现预期结果。如果属性和值不存在,那么它需要具有 "-"。 .

请帮我将当前结果转换为预期结果..

【问题讨论】:

  • 但两种产品的值不同,您还想删除吗?
  • @PardeepJain,您可以在预期结果中看到产品二下的值已达到顶部。如果您比较两个结果,您就会明白我的意思。
  • 两个数组大小相同?
  • @Justcode,不,它会根据服务是动态的..两者的大小不同..
  • 那么,当product_3来的时候,你会手动合并数组吗?

标签: javascript angular typescript angular5 angular6


【解决方案1】:

Something like this

可能有更好的格式化数据的方法,但想法应该几乎相同。 或者,您可以尝试将对象格式化为以下格式:

[ 
{ "propName": "length", "one": 12, "two": 20 },
{ "propName": "width", "one": 12, "two": '-'}
...
]

或者将“一”和“二”组合成一个数组,方便扩展。

【讨论】:

  • 如果我有很多产品而不是两个会怎样??
  • 对于 n 个产品,您可能想要一个 productArray = ['one', 'two' ... ] 并执行 {{ getPropertyVal(product , property) }}
【解决方案2】:

结果不正确,因为您合并产品逻辑错误。我做了一些小的改动来展示如何更正数据以显示你想要的。

ngOnInit() {
  this.mergedProductProperties = {};
  this.products.productOne.forEach(element => {
    this.productOneDetails = element.product_name;
    element.productOneProperties.type  = "one";

    element.productOneProperties.forEach(item => {
      this.mergedProductProperties[item.property_name] =this.mergedProductProperties[item.property_name] || [];
      this.mergedProductProperties[item.property_name][0] = item.property_value;
     });
   });

  this.products.productTwo.forEach(element => {
    this.productTwoDetails = element.product_name;
     element.productTwoProperties.type  = "two";

     element.productTwoProperties.forEach(item => {
       this.mergedProductProperties[item.property_name] = this.mergedProductProperties[item.property_name] || [];
       this.mergedProductProperties[item.property_name][1] = item.property_value;
     });
   });
  console.log(this.mergedProductProperties);
  for(var key in this.mergedProductProperties){
     this.mergedArray.push({
       property_name: key,
       property_value: this.mergedProductProperties[key]
     })
  }
  console.log(this.mergedArray);
}

html 将被改变

<tbody>
    <tr *ngFor="let item of mergedArray">
  <td> {{ item.property_name }} </td>
    <td *ngFor="let val of item.property_value">{{val}}</td>
    </tr>
</tbody>

【讨论】:

    【解决方案3】:

    首先你的结构加错了,你必须考虑你的结构使用flattern,如果你这样做会容易得多。

    让我们考虑处理这个结构。

    您需要在组件中定义三个变量

      headers: any;
      data: any;  
      properties:any;
    

    首先你需要得到标题

     var headers = Object.keys(this.products).reduce((prev, next) => {
          prev.push({ name: this.products[next][0].product_name, id: next });
          return prev;
        }, []);
    

    然后,获取属性和数据

     let data = [];
        let propertiesData = [];
        headers.forEach(a => {
          const properties = this.products[a.id][0][a.id + "Properties"];
          data.push({id:a,properties:properties});
          propertiesData.push(properties);
        });
    

    然后将此变量分配给标题、数据和属性

    propertiesData = propertiesData.flat().filter((thing, index, self) =>
          index === self.findIndex((t) => (
            t.property_name === thing.property_name
          ))
        )
    
        this.headers = headers;
        this.data = data;
        this.properties = propertiesData;
    

    所以,您现在拥有三样东西,标题数据和唯一的属性,

    现在,您需要一种方法来根据数据过滤掉此属性名称,

     getPropertyData(propertyName,item){        
        var value= item.properties.filter(a=> a.property_name === propertyName);
        if(value.length>0){
          return value[0].property_value;
        }else{
          return "-";
        }
      }
    

    现在,在您看来,您可以像这样重组您的表格

    <table>
        <thead>
            <tr>
                <th>
                    Property Details
                </th>
                <th *ngFor="let item of headers">
                    {{item.name}}
                </th>
            </tr> <br>
        </thead>
        <tbody>
            <tr *ngFor="let item of properties">
          <td>{{item.property_name}}</td>
          <td *ngFor="let itemData of data">
            {{getPropertyData(item.property_name,itemData)}}
                </td>
            </tr>
        </tbody>
    </table>
    

    因此,这将过滤掉产品的属性数据。

    这里是stackblitz demo。请记住,使用该结构有一些缺点。比如你的第三个属性必须是productThreeProperties的名称

    【讨论】:

    • 评论不用于扩展讨论;这个对话是moved to chat
    • 请在这种情况下单独帮助我为什么我在这个 stackblitz 中遇到错误? stackblitz.com/edit/flatternstructure-mc3zjq .. 我添加的东西是在 template_details 数组中创建另一个对象.. 并给出 a.template_information.template_details[index] 而不是 a.template_information.template_details[0] 因为我可能有多个 template_details 因为它是一个数组..