删除列中的重复名称
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
</th>
<th>
{{productOneDetails}}
</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>
这里我有两个单独的产品和属性,其中 属性 名称(例如 Length
和 Width
对两个产品都有 重复 不同的值..
工作 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 帮助我将当前结果转换为预期结果..
可能有更好的数据格式设置方法,但原理应该差不多。
或者,您可以尝试将对象格式化为以下格式:
[
{ "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
的名字
在我的 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
</th>
<th>
{{productOneDetails}}
</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>
这里我有两个单独的产品和属性,其中 属性 名称(例如 Length
和 Width
对两个产品都有 重复 不同的值..
工作 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 帮助我将当前结果转换为预期结果..
可能有更好的数据格式设置方法,但原理应该差不多。 或者,您可以尝试将对象格式化为以下格式:
[
{ "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