删除列中的重复名称

时间:2018-12-18 05:47:37

标签: javascript angular typescript angular5 angular6

在我的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

请通过将重复的属性名称显示为唯一并显示相邻的值来帮助我达到预期的结果。如果属性和值不存在,则需要具有“-”

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

3 个答案:

答案 0 :(得分:1)

Something like this

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

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

或将“一个”和“两个”组合成一个数组以使扩展更容易。

答案 1 :(得分:1)

首先,您的结构添加得很不正确,您必须考虑使用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

答案 2 :(得分:0)

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

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>