Получить объект в массиве, который содержит наиболее подходящее свойство id в строке? - PullRequest
0 голосов
/ 20 октября 2018

Мне интересно, есть ли лучший способ добиться результата.У меня есть массив объектов, каждый объект содержит идентификатор в качестве шаблона пути строки.Я хочу вернуть объект, который наилучшим образом соответствует пути URL.Я использую lodash

Все идентификаторы уникальны.

const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{
  '_id': '/la-nacion/economia'
}, {
  '_id': '/la-nacion'
}, {
  '_id': '/la-nacion/economia/finanzas'
}, {
  '_id': '/la-nacion/economia/moodys'
}]

const urlArr = url.split('/')

const compare = sites.map(site => {
  // get all matches
  const siteArr = site._id.split('/')
  // get lengths of matches
  return _.intersection(siteArr, urlArr).length
})
// get index of obj with best match
const indexOfBestMatch = _.indexOf(compare, _.max(compare))
// new primary section
const newPrimarySection = sites.filter((e, i) => {
  return i === indexOfBestMatch
})

console.log(newPrimarySection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

https://jsbin.com/lumepereyi/1/edit?js,console

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Поскольку вам нужен только элемент с максимальным соответствием, вы можете использовать _.maxBy() для итерации массива сайтов и извлечения элемента.Используйте _.get() для извлечения значения _id, потому что _.get() не выдаст ошибку, если sites пусто:

const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{"_id":"/la-nacion/economia"},{"_id":"/la-nacion"},{"_id":"/la-nacion/economia/finanzas"},{"_id":"/la-nacion/economia/moodys"}]

const getPrimarySection = (url, sites) => {
  const urlArr = url.split('/')

  return _.get(_.maxBy(sites, site => {
    const siteArr = site._id.split('/')
    return _.intersection(siteArr, urlArr).length
  }), '_id')
}

const newPrimarySection = getPrimarySection(url, sites)

console.log(newPrimarySection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
0 голосов
/ 21 октября 2018

Если ваш префикс path всегда один и тот же (как, кажется, с /la-naction, то вы можете сделать свой собственный подсчет очков (через startsWith) на основе длины совпадающей строкиа затем sort-by desc (наибольшее количество баллов) ... и наберите лучший результат:

const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/'
const sites = [{"_id":"/la-nacion/economia"},{"_id":"/la-nacion"},{"_id":"/la-nacion/economia/finanzas"},{"_id":"/la-nacion/economia/moodys"}]

const getBestMatch = (s, u, p = '/la-nacion') => {  // <-- default prefix
  const topScored = s.map(x =>
    (Object.assign(x, {
      score: ((`${p}${u}`).startsWith(x._id) ? x._id.length : 0)}), x)
    ).sort((a, b) => b.score - a.score)[0]   // <-- sort, get the highest score
  return topScored.score > 0 ? topScored._id : undefined
}

console.log(getBestMatch(sites, url))

Нет необходимости в Лодаше и т. Д. Просто map добавьте счет, а затем sort действительно.

0 голосов
/ 20 октября 2018

Нет необходимости в библиотеке, вы можете использовать reduce для итерации по массиву _id s, сохраняя счетчик количества совпадений подстрок, чтобы он преобразовывался в тот, у которого наибольшее количество совпадений:

const url = '/economia/finanzas/moodys-coloca-calificaciones-de-riesgo-de-costa/JZF24QAQHBBFPLJQL5VZJPKCZA/story/';
const sites = [{
  '_id': '/la-nacion/economia'
}, {
  '_id': '/la-nacion'
}, {
  '_id': '/la-nacion/economia/finanzas'
}, {
  '_id': '/la-nacion/economia/moodys'
}];


const substrings = new Set(url.split('/'));
const countMatches = str => str.split('/').reduce((a, substr) => a + (substrings.has(substr)), 0);
const { bestMatch } = sites.reduce(({ bestMatch, count=0 }, { _id }) => {
  const thisCount = countMatches(_id);
  return thisCount > count
  ? { count: thisCount, bestMatch: _id }
  : { count, bestMatch };
}, {});
console.log(bestMatch);
...