prioritize pushing element to array

Viewed 52

I have an array with objects as elements. What I did was check if the titles value contains a certain string and it it does push that a new array and log the new array and the process works.

What I want is when pushing to the new array I want to prioritize the string found first to be pushed first.

To explain it better say my array is this:

myArr = [{"title": "test hello"}, {"title": "hello test"}, {"title": "test test"}]

If my search string is hello I want my new array to be this:

[{"title": "hello test"}, {"title": "test hello"}]

The search string found first will be put first. How can I achieve this? Thanks in advance.

const myArr = [{
  "title": "test hello"
}, {
  "title": "hello test"
}, {
  "title": "test test"
}]

const searchValue = 'Hello'

let foundArr = []

for (var i = 0; i < myArr.length; i++) {
  if (myArr[i].title.toLowerCase().includes(searchValue.toLowerCase())) {
    foundArr.push(myArr[i])
  }
}

//expected output [{"title": "hello test"}, {"title": "test hello"}]
console.log(foundArr)

3 Answers

To achieve what you require you could sort() the array by the index of the matched string within the value.

Also, you can simplify the logic by using filter() to find matches instead of an explicit for loop:

const myArr = [
  { title: "test hello" }, 
  { title: "hello test" }, 
  { title: "test test" }, 
  { title: "foo hello test" }
]

const searchValue = 'Hello'.toLowerCase();
let foundArr = myArr
  .filter(o => o.title.toLowerCase().includes(searchValue))
  .sort((a, b) => a.title.toLowerCase().indexOf(searchValue) > b.title.toLowerCase().indexOf(searchValue) ? 1 : -1);

console.log(foundArr)

You can try to use Array.reduce

Logic:

  • Loop over values and fetch index of string
  • Use index as key and insert it in object
  • At the end, delete "-" as they are non-matching elements
  • Return values of this object's values

const myArr = [{"title": "test hello"}, {"title": "hello test"}, {"title": "test test"}]
const searchValue = 'Hello'

const matches = myArr.reduce((acc, item) => {
  const index = item.title.toLowerCase().indexOf(searchValue.toLowerCase())
  acc[index] = item
  return acc
}, {})
delete matches["-1"];
console.log(Object.values(matches))

You can use the string member method indexOf to acquire the index of a matching pattern. Afterwards filter out any non matching elements.



const myArr = [
  {
    title: "test hello"
  },
  {
    title: "hello test"
  },
  {
    title: "test test"
  }
];

const searchValue = "Hello";

const result = myArr
  .map(({ title }) => {
    var index = title
      .toLocaleLowerCase()
      .indexOf(searchValue.toLocaleLowerCase());

    
    return {
      match: index >= 0,
      index: index,
      title
    };
  })
  .filter(({ match }) => match)
  .sort((a, b) => a.index - b.index);

//expected output [{"title": "hello test"}, {"title": "test hello"}]
console.log(result);

On such problems, try not to iterate too often through your arrays.

Related