删除列中的重复名称

Remove duplicate names in a column

在我的 angular 6 应用程序中,我正在使用 products 数组中的内容制作一个 table,例如,

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 对两个产品都有 重复 不同的值..

工作 stackblitz: 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

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

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

Something like this

可能有更好的数据格式设置方法,但原理应该差不多。 或者,您可以尝试将对象格式化为以下格式:

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

或者将 "one" 和 "two" 组合成一个数组,使扩展更容易。

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

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>

首先你的结构添加的很错误,你必须考虑你的结构使用扁平化,如果你这样做会更容易。

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

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

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

首先你需要得到 headers

 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);
    });

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

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;

所以,您现在拥有三样东西,headers 数据和属性,它们是独一无二的,

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

 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 来喜欢这个

<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

的名字