skip to Main Content

We have list of data + query string, we need to modify an autocomplete filter logic to show post spots first and then other string which could be streets.

// external sorted data usually by name
var data = [
    '45 Some street, bla bla',
    'Again 45 street some',
    'More some street xyz',
    'Guess what? Some street',
    'Post spot №345',
    'Post spot №45',
    'Post spot №66745' 
];

// user input
var query = '45';

// here goes some filter magic

/* RESULT must be

1. Post spot №45 // here "45" appears the closest to "№"
2. Post spot №345 // next closest "45" to "№"
3. Post spot №66745 // last closest "45" to "№"
4. 45 Some street, bla bla // here "45" is start of the string BUT it does not come with "№" on the left, but it the heaviest from other data with no "№" on the left
5. Again 45 street some // next heavy item with "45"
--------
in 4 and 5 could be whatever string, not just "45", search logic must sort it with the closest substring to the start of the query string
*/

So as summary it must work like this:

  1. If query is number then search for "№" on the left -> if found make it heavy and sort from similar items (all of such items must be at the top of the result list)
  2. If query is number or string (not matter) then just sort it with substring position leaders (all of these items comes after items #1)

I broke my brain how to make it as short as possible, help me please!

Or if you know cool and nice pure JS autocomplete with builtin search hook (but the logic is still needed) please let me know!

2

Answers


  1. To achieve the desired autocomplete filter logic where post spots are shown first, followed by other strings (streets), you can use the following approach:

    // External sorted data usually by name
    var data = [
      '45 Some street, bla bla',
      'Again 45 street some',
      'More some street xyz',
      'Guess what? Some street',
      'Post spot №345',
      'Post spot №45',
      'Post spot №66745' 
    ];
    
    // User input
    var query = '45';
    
    // Filter logic
    var filteredData = data.filter(function(item) {
      if (query.match(/^d+$/)) {
        // Query is a number
        if (item.includes('№')) {
          return item.includes(query) && item.indexOf('№') < item.indexOf(query);
        }
      } else {
        // Query is a string
        return item.includes(query);
      }
    });
    
    // Sort the filtered data
    filteredData.sort(function(a, b) {
      var aIndex = a.indexOf(query);
      var bIndex = b.indexOf(query);
    
      return aIndex - bIndex;
    });
    
    // Print the filtered and sorted data
    console.log(filteredData);
    

    This code filters the data based on the query string and sorts the filtered data using the position of the query substring. For numbers, it checks if the item includes the query and if the item has ‘№’ on the left side of the query. For strings, it simply checks if the item includes the query.

    The resulting filtered and sorted data will have post spots (with ‘№’ on the left) listed first, followed by other strings sorted based on their substring position.

    Please note that this is a simplified example based on the provided data and query. You may need to adjust it according to your specific requirements and the actual data and query handling in your application.

    Login or Signup to reply.
  2. you can try out the following code snippet to understand how to filter and sort data based on specific criteria. This code is designed to help you learn about filtering and sorting arrays in JavaScript. Use the "Run Code Snippet" button from stackoverflow at the end. Let’s dive in!

        // External sorted data usually by name
        var data = [
          '45 Some street, bla bla',
          'Again 45 street some',
          'More some street xyz',
          'Guess what? Some street',
          'Post spot №345',
          'Post spot №45',
          'Post spot №66745'
        ];
    
        // User input
        var query = '45';
    
        // Filter function
        function filterData() {
          var filteredData = [];
          var containsNumberSign = [];
          var doesNotContainNumberSign = [];
    
          // Separate items that contain "№" from those that don't
          data.forEach(function(item) {
            if (item.includes(query)) {
              if (item.includes('№')) {
                containsNumberSign.push(item);  // Add item to the array that contains "№"
              } else {
                doesNotContainNumberSign.push(item);  // Add item to the array that doesn't contain "№"
              }
            }
          });
    
          // Sort the arrays by name
          containsNumberSign.sort();
          doesNotContainNumberSign.sort();
    
          // Combine the sorted arrays
          filteredData = containsNumberSign.concat(doesNotContainNumberSign);
    
          // Get the result element
          var resultElement = document.getElementById("result");
    
          // Clear previous result
          resultElement.innerHTML = "";
    
          // Display the filtered data
          filteredData.forEach(function(item) {
            var itemElement = document.createElement("p");
            itemElement.textContent = item;
            resultElement.appendChild(itemElement);
          });
        }
    <body>
      <button onclick="filterData()">Show Filtered Data</button>
      <div id="result"></div>
    </body>

    Good luck on your learning journey!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search