У меня есть массив с объектами в качестве элементов. Что я сделал, так это проверил, содержит ли значение titles определенную строку, и оно действительно подталкивает этот новый массив и регистрирует новый массив, и процесс работает.
Что я хочу, так это то, что при нажатии на новый массив я хочу расставить приоритеты в строке, найденной первой, которая будет сначала нажата.
Чтобы объяснить это лучше, скажите, что мой массив таков:
myArr = [{"title": "test hello"}, {"title": "hello test"}, {"title": "test test"}]
Если моя строка поиска hello, я хочу, чтобы мой новый массив был таким:
[{"title": "hello test"}, {"title": "test hello"}]
Строка поиска, найденная первой, будет помещена первой. Как я могу этого добиться? Заранее спасибо.
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.info(foundArr)Так что просто найти это слово для вас недостаточно. Вам нужно ранжировать их с определенными типами соответствия. (совпадение в начале предложения имеет более высокий приоритет)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Чтобы добиться того, что вам нужно, вы можете sort() массив по индексу совпадающей строки в значении.
Кроме того, вы можете упростить логику, используя filter() для поиска совпадений вместо явного цикла for:
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.info(foundArr)по какой-то причине он не работает с моим массивом, взгляните на это jsfiddle.net/#&togetherjs=RsIrVR4eLd
Можете ли вы сохранить скрипку и поделиться ею? Это открывает пустую скрипку для меня
вот новая рабочий пример jsfiddle.net/#&togetherjs=RsIrVR4eLd
@Rajesh взгляните на скрипку выше. Мой массив довольно большой, поэтому обязательно прокрутите все, что было вниз.
Мне кажется, работает нормально. Вы делаете 1 ошибку. Оператор сравнения должен быть больше не меньше. Для вашей справки
@Rajesh да, это была проблема, спасибо за помощь
Вы можете попробовать использовать Array.reduce
"-", так как это не совпадающие элементы.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.info(Object.values(matches))Вы можете использовать метод члена строки indexOf, чтобы получить индекс соответствующего шаблона. Затем отфильтруйте все несоответствующие элементы.
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.info(result);
При таких проблемах старайтесь не слишком часто перебирать свои массивы.
Вероятно, вы захотите использовать нечеткий поиск. fuse.js может быть полезен. Если вы хотите сделать это без библиотеки, вы можете использовать indexOf и сортировать по нему