通过密钥B的最大值

时间:2019-01-12 18:27:55

标签: javascript javascript-objects

如果这是一个简单的问题,请提前抱歉。我知道过滤对象和数组已从各个角度进行了介绍,只是在努力了解如何在这种情况下实现它。

我有一个来自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);

2 个答案:

答案 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);