获取数组中包含字符串中最匹配ID属性的对象?

时间:2018-10-20 03:37:23

标签: javascript arrays object underscore.js lodash

我想知道是否有更好的方法来获得结果。 我有一个对象数组,每个对象都包含一个ID作为字符串路径模式。我想将最匹配的对象返回到URL路径。我正在使用lodash的ATM

所有ID都是唯一的。

[['|' if x-1 <= i <= x+1 and y-1 <= j <= y+1\
  and (myList[j][i] == '.') else myList[j][i]\
  for i in range(len(myList[y]))] for j in range(len(myList))]
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)

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

3 个答案:

答案 0 :(得分:1)

不需要库,您可以使用reduce遍历_id的数组,并保持对子字符串匹配数的计数,以便将其解析为最多的匹配项:

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

答案 1 :(得分:0)

由于只需要具有最大匹配项的项目,因此可以使用_.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>

答案 2 :(得分:0)

如果,您的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