Mam tablicę ciągów. Muszę posortować tablicę na podstawie szeregu słów kluczowych. Ciąg zawierający max. Liczba słów kluczowych powinna być pierwsza i tak dalej. Również ciąg, który zawiera max. Nie. wyszukiwania Słowa kluczowe powinny przyjść najpierw niż liczba zdarzeń tego samego słowa kluczowego wyszukiwania. testArray powinien ignorować obudowę searchTerms. Jeśli to możliwe, możesz zignorować struny, które nie zawierają słów kluczowych wyszukiwania w tablicy wynikowej.

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>

Jeśli obserwujesz w powyższym kodzie, słowa kluczowe są "I", "right","know". Więc wyniki testArray powinny być jak poniżej,

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

Ciąg zawierający wszystkie słowa kluczowe są najpierw, a inne struny zawierają "I","know", więc przychodzą dalej, a ciąg {X1}} jest ostatni, ponieważ zawiera tylko słowo kluczowe "I".

Codepen

1
Raviteja 4 czerwiec 2018, 12:01

3 odpowiedzi

Najlepsza odpowiedź

Możesz spróbować czegoś takiego:

Pomysł:

  • Pętla nad danymi i kryteriami i utworzyć mapę, która ma zarówno liczbę, jak i wartość.
  • Użyj regexa, aby dopasować ciąg. W ten sposób możesz wykonywać poszukiwanie wszechstronności.
  • Sortuj tę mapę na podstawie liczenia.
  • Lista zwrotów wartości.
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))
1
Community 20 czerwiec 2020, 09:12

Możesz wziąć obiekt na liczenie i uporządkowanie według liczby ciągu.

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
Nina Scholz 5 czerwiec 2018, 09:04

Możesz spróbować utworzyć regex z tymi warunkami według liczby meczów, coś w rodzaju:

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);
1
J. Pichardo 4 czerwiec 2018, 10:33