Отфильтруйте элементы в объекте с дублированным ключом A по наибольшему значению ключа B - PullRequest
0 голосов
/ 12 января 2019

Извините, если это простой вопрос. Я знаю, что фильтрация объектов и массивов была покрыта со всех сторон, и я просто пытаюсь понять, как реализовать это в этом случае.

У меня есть объект предметов из JSON, каждый из которых предлагается несколькими провайдерами различного качества (а также множество другой информации, которую я не включил ниже).

Я пытаюсь отфильтровать этот оригинальный объект, чтобы он возвращал новый объект, содержащий только лучшее качество предложения для каждого идентификатора поставщика предложения (а также остальную информацию для этой записи).

Качествами являются все известные строковые значения, содержащиеся в массиве в порядке убывания предпочтения.

Итак, у меня есть:

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"}]

И отфильтровывать дублирующиеся предложения от того же поставщика с более низкими качествами.

Я чувствовал, что это должно быть v. Просто - использовать либо вспомогательный массив для циклов, либо lodash или что-то в этом роде.

Я пытался провести его через цикл for, добавляя каждого нового провайдера по мере его появления и обновляя его только в следующий раз, если это более высокое предложение, но мой JavaScript не силен, и по какой-то причине я просто могу не поймите это!

Любой совет будет с благодарностью!

Спасибо, Alex

EDIT: как предложил бармар, я еще раз взглянул на свой код и добавляю его сюда. Я думаю, что заставил это работать - но это кажется немного медленным и очень неуклюжим, так что помощь все равно будет высоко ценится!

    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 голосов
/ 12 января 2019

Поиск в массиве идентификатора провайдера каждый раз очень неэффективен, вы должны использовать объект, ключом которого является идентификатор провайдера.

Кроме того, превратите качества в объект, который сопоставляет ключевые слова со значениями (или просто хранит числа в объектах и ​​переводит их в слово при отображении).

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);
0 голосов
/ 12 января 2019

Вы можете взять 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; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...