Récupère l'objet dans le tableau qui contient le plus proche propriété id correspondant dans une chaîne?

voix
0

Je me demande s'il y a une meilleure façon de faire obtenir le résultat. Je un tableau d'objets, chaque objet contient un identifiant en tant que motif de trajet de chaîne. Je veux retourner l'objet qui a la meilleure correspondance à un chemin d'URL. ATM J'utilise lodash

Tous les id sont uniques.

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

Créé 20/10/2018 à 03:37
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
1

Pas besoin d'une bibliothèque, vous pouvez utiliser reducepour itérer sur le tableau de _ids, en gardant un décompte du nombre de correspondances de sous, de sorte qu'il décide de celui avec le plus de matches:

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

Créé 20/10/2018 à 03:45
source utilisateur

voix
0

Si votre pathpréfixe est toujours le même (comme il semble que ce soit avec /la-nactionvous pouvez faire votre propre notation (via startsWith) en fonction de la longueur de la chaîne apparié puis sort-by desc( le plus grand score) ... et prendre le score:

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))

Non lodash NEEED etc , il est juste mapd'ajouter le score et sortvraiment.

Créé 20/10/2018 à 21:09
source utilisateur

voix
0

Puisque vous ne devez l'élément avec les matches max, vous pouvez utiliser _.maxBy()pour itérer le réseau de sites, et extraire l'élément. Utilisez _.get()pour extraire la valeur de _id, car _.get()ne génère pas d'erreur si sitesest vide:

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>

Créé 20/10/2018 à 04:31
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more