Я создаю инструмент для своего клиента, который группирует ключевые слова на основе 10 самых популярных поисковых запросов Google. Ключевое слово представлено в виде объекта JavaScript, содержащего массив URL-адресов. Критерием группировки является то, что два ключевых слова принадлежат к одной группе, если они имеют 3 или более общих URL . Кроме того, должно быть без дублирования ключевых слов в сгенерированных группах, и общее количество сгенерированных групп не предопределено перед группировкой. Я был бы признателен за любые советы по логике части этой проблемы, спасибо!
До сих пор мне удавалось разработать алгоритм, представленный ниже, но он все еще делает дубликаты и не группирует ключевое слово 100% справа (некоторые ключевые слова должны быть в той же группе, но это не так).
function makeKeywordGroupsNew(results: Result[], uid: string): Group[] {
let dataset = results;
let groups: any[] = [];
// loop thru all records in dataset
dataset.forEach((current: Result) => {
// initialize the group with the current keyword in it
const group = { volume: 0, items: [current] };
// remove the current keyword from the dataset
dataset = dataset.filter(el => el.keyword !== current.keyword);
// loop thru the new dataset and push the other keyword into the group if it has >=3 urls in common with current keyword
dataset.forEach((other: Result) => {
const urlsInCommon = _.intersection(current.urls, other.urls);
if (urlsInCommon.length >= 3) {
group.items.push(other);
}
});
// sum the keyword volumes to form the group volume - not important for the core logic
// @ts-ignore
group.volume = _.sum(group.items.map(item => item.volume));
// sort keywords in the formed group by volume - not important for the core logic
// @ts-ignore
group.items = group.items
.sort((a, b) => {
if (a.volume < b.volume) return 1;
if (a.volume > b.volume) return -1;
return 0;
})
.map(el => el.keyword);
// add the newly formed group to the groups array (the result)
groups.push(group);
});
// exclude the groups with only one keyword inside
groups = groups.filter(group => group.items.length > 1);
// delete keyword duplicates inside of the group
groups = groups.map(group => ({ ...group, items: _.uniq(group.items) }));
// form the correct result object shape - not important for the core logic
return groups.map(group => ({
uid,
main: group.items[0],
keywords: group.items.slice(1, group.length),
volume: group.volume
}));
}
Я ожидал, что результат input.json будет output.csv , но мое решение либо помещает меньше ключевых слов в группу, либо создает неправильные группы.