如何根据搜索关键字对字符串数组进行排序?

时间:2018-06-04 09:01:35

标签: javascript arrays sorting

我有一系列字符串。我需要根据关键字数组对数组进行排序。 包含最大值的字符串关键字的数量应首先出现,依此类推。另外,包含最大值的字符串。没有。搜索关键字的首先应该是相同搜索关键字的出现次数。 testArray应该忽略searchTerms的情况。如果可能,您可以忽略结果数组中不包含任何搜索关键字的字符串。



var testArray = [
    "I am",
    "I am wrong and I don't know",
    "I am right and I know",
    "I don't know",
    "I do know"
  ],
  searchTerms = ["I", "right","know"];

$.each(searchTerms, function(index, term) {
  var regX = new RegExp(term, "i");
  testArray = $.map(testArray, function(item) {
    if (regX.test(item)) {
      return item;
    } else {
      return;
    }
  });
});

console.log(testArray);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

如果您在上面的代码中观察到,则关键字为"I", "right","know"。因此,testArray结果应如下所示,

testArray = [
    "I am right and I know",    
    "I am wrong and I don't know",    
    "I don't know",
    "I do know",
    "I am"
  ]

字符串首先包含所有关键字,其他字符串包含"I","know",因此它们紧随其后,字符串"I am"位于最后,因为它只包含"I"个关键字。

Codepen

3 个答案:

答案 0 :(得分:1)

你可以拿一个对象进行计数,然后按字符串的数量排序。

var array = [ "I am", "I am wrong and I don't know", "i am RIGHT and I know", "I don't know", "I do know", "i,i,i will come first i'm RIGHT i do KNOW"],
    search = ["I", "am","know"].map(v => v.toLowerCase()),
    count = array.reduce((c, k) => {
        var a = k.toLowerCase().split(/[^a-z0-9']+/),
            count = Object.create(null);

        a.forEach(w => count[w] = (count[w] || 0) + 1);
        c[k] = [0, 0];
        search.forEach(v => {
            c[k][0] += v in count;
            c[k][1] += count[v] || 0;
        });
        return c;
    }, Object.create(null));
  
array.sort((a, b) => count[b][0] - count[a][0] || count[b][1] - count[a][1]);

console.log(array);

答案 1 :(得分:1)

您可以尝试使用这些术语创建正则表达式,并按匹配数排序,例如:

&#13;
&#13;
var testArray = [
    "I am",
    "i,i,i will come first i'm RIGHT i do KNOW",
    "I am wrong and I don't know",
    "I am right and I know",
    "I don't know",
    "I do know",
    "Something else"
  ],

  searchTerms = ["I", "right", "know"];


// (?:I)|(?:right)|(?:know)
const searchExp = new RegExp(searchTerms.reduce((acc, term) => acc ? `${acc}|(?:${term})` : `(?:${term})`, ''), 'gi');

const result = testArray.sort((a, b) => {
  const bMatch = b.match(searchExp) || [];
  const aMatch = a.match(searchExp) || [];

  return bMatch.length - aMatch.length;
});

console.log(result);
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以尝试这样的事情:

思想:

  • 循环数据和条件,并创建一个既有计数又有值的地图。
  • 使用正则表达式匹配字符串。这样您就可以进行不区分大小写的搜索。
  • 根据计数对此地图进行排序。
  • 返回值列表。

&#13;
&#13;
function getMatchCountMap(data, criterias) {
  return data.reduce((countMap, curItem) => {
    var count = criterias.filter((criteria) => new RegExp(criteria, 'i').test(curItem) ).length;
    countMap.push({
      value: curItem,
      count: count
    });
    return countMap;
  }, [])
}

function sortBasedOnCount(data, criterias) {
  var map = getMatchCountMap(data, criterias);
  map.sort((a, b) => b.count - a.count);
  return map.map(x => x.value);
}

var testArray = [
    "I am",
    "I am wrong and I don't know",
    "I am right and I know",
    "I don't know",
    "I do know"
  ],
  searchTerms = ["I", "right","know"];
  
console.log(sortBasedOnCount(testArray, searchTerms))
&#13;
&#13;
&#13;