如果这是一个简单的问题,请提前抱歉。我知道过滤对象和数组已从各个角度进行了介绍,只是在努力了解如何在这种情况下实现它。
我有一个来自JSON的项目对象,每个项目都是由多个提供商以不同的质量提供的(以及我下面未包括的其他信息的负载)。
我正在尝试过滤此原始对象,以返回一个仅包含每个商品提供者ID(以及该条目的其余信息)的最佳商品质量的新对象。
质量是所有已知的字符串值,按优先级降序包含在数组中。
所以我有:
const qualities = ["great", "good", "bad", "awful"];
const offerings =
[{item_id: 1,
offering_provider_id: 1,
offering_quality: "good",
link: "abc.xyz"},
{item_id: 1,
offering_provider_id: 1,
offering_quality: "great",
link: "abc.xyz"},
{item_id: 1,
offering_provider_id: 2,
offering_quality: "bad",
link: "xyz.abc"}]
我想返回:
const filteredOfferings =
[{item_id: 1,
offering_provider_id: 1,
offering_quality: "great",
link: "abc.xyz"},
{item_id: 1,
offering_provider_id: 2,
offering_quality: "bad",
link: "xyz.abc"}]
并筛选出质量较低的同一提供商的重复产品。
我觉得它一定很简单-使用辅助数组和for循环,或lodash之类的东西。
我试图通过一个for循环,在出现每个新提供程序时将其添加,并且只有在提供更高版本时才下次进行更新,但是我的javascript不够强大,出于某种原因,我可以没办法!
任何建议将不胜感激!
谢谢, 亚历克斯
编辑: 正如barmar建议的那样,我再次查看了我的代码并将其添加到此处。 我想我已经做到了-但它似乎有点慢并且非常笨拙,因此仍然非常感谢您的帮助!
const filteredOffersArray = [];
const providerHighestOffering = [];
for(var i= 0, l = offerings.length; i< l; i++){
if ( providerHighestOffering.some(item => item.offering_provider_id_and_type === offerings[i].offering_provider_id+offerings[i].offering_provider_type) )
{
var currentOfferingQuality = providerHighestOffering.find(item => item.offering_provider_id_and_type === offerings[i].offering_provider_id+offerings[i].offering_provider_type).offering_quality;
var newOfferingQuality = offerings[i].offering_quality;
if ( qualities.indexOf(newOfferingQuality) < qualities.indexOf(currentOfferingQuality) ) {
var currentHighestOfferingIndex = providerHighestOffering.findIndex(item => item.offering_provider_id_and_type===offerings[i].offering_provider_id+offerings[i].offering_provider_type);
providerHighestOffering.splice(currentHighestOfferingIndex, 1);
providerHighestOffering.push( { original_array_position: i, offering_provider_id_and_type: offerings[i].offering_provider_id+offerings[i].offering_provider_type, offering_provider_id : offerings[i].offering_provider_id, offering_provider_type : offerings[i].offering_provider_type, offering_quality : offerings[i].offering_quality } );
}
} else {
providerHighestOffering.push( { original_array_position: i, offering_provider_id_and_type: offerings[i].offering_provider_id+offerings[i].offering_provider_type, offering_provider_id : offerings[i].offering_provider_id, offering_provider_type : offerings[i].offering_provider_type, offering_quality : offerings[i].offering_quality } );
}
}
for(var i= 0, l = offerings.length; i< l; i++){
if(providerHighestOffering.some(item => item.original_array_position === i)) {
filteredOffersArray.push(offerings[i]);
}
}
console.log(filteredOffersArray);
答案 0 :(得分:0)
您可以使用Map
并以最高质量存储对象。
const
qualities = ["great", "good", "bad", "awful"],
getQuality = q => qualities.length - qualities.indexOf(q),
offerings = [{ item_id: 1, offering_provider_id: 1, offering_quality: "good", link: "abc.xyz" }, { item_id: 1, offering_provider_id: 1, offering_quality: "great", link: "abc.xyz" }, { item_id: 1, offering_provider_id: 2, offering_quality: "bad", link: "xyz.abc" }],
filtered = Array.from(offerings
.reduce(
(m, o) => (item => m.set(o.item_id, item && getQuality(item.offering_quality) > getQuality(o.offering_quality) ? item : o))
(m.get(o.item_id)),
new Map
)
.values()
);
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
每次在数组中搜索提供者ID的效率都非常低,您应该使用键为提供者ID的对象。
此外,使质量成为对象,该对象将关键字映射为值(或仅将数字存储在对象中,并在显示时将其转换为单词)。
const qualities = {
"great": 4,
"good": 3,
"bad": 2,
"awful": 1
};
const offerings = [{
item_id: 1,
offering_provider_id: 1,
offering_quality: "good",
link: "abc.xyz"
},
{
item_id: 1,
offering_provider_id: 1,
offering_quality: "great",
link: "abc.xyz"
},
{
item_id: 1,
offering_provider_id: 2,
offering_quality: "bad",
link: "xyz.abc"
}
];
const by_provider = {};
offerings.forEach(o => {
if (!by_provider[o.offering_provider_id] || qualities[by_provider[o.offering_provider_id].offering_quality] < qualities[o.offering_quality]) {
by_provider[o.offering_provider_id] = o;
}
});
const filtered_offerings = Object.values(by_provider);
console.log(filtered_offerings);