#javascript #arrays #reactjs #filter
#javascript #массивы #reactjs #Фильтр
Вопрос:
У меня есть два массива — фактический массив содержит 2500 записей, теперь их немного для примера). Я реализовал функцию поиска в реальном времени в react native. Это моя функция,
Таким образом, когда пользователь вводит что-либо, оно фильтрует и отображает во flatlist! Это работает отлично, но дело в том, что у меня есть другой array2, в котором у него есть псевдонимы для городов в array1 (примечание: не у всех городов есть псевдонимы). Мой вопрос в том, как объединить оба для фильтрации,
Например: когда пользователь вводит «Tiruchirapalli» или «Trichy», он должен показывать имя псевдонима, а для городов, у которых нет псевдонима, должно быть показано его оригинальное название!
Как этого добиться ?
Array1
const array1 = [{
"id": "117",
"name": "Tiruchirapalli",
"stateId": "101"
},
{
"id": "27110",
"name": "Ganoda",
"stateId": "1405"
},
{
"id": "203",
"name": "Tenkasi",
"stateId": "101"
},
{
"id": "115",
"name": "Thanjavur",
"stateId": "101"
},
];
Массив2
const array2 = [{
"id": 1850,
"cityName": "Tenkasi",
"aliasNames": [
"Thenkasi"
]
},
{
"id": 4521,
"cityName": "Tiruchirapalli",
"aliasNames": [
"Trichy"
]
},
{
"id": 115,
"cityName": "Thanjavur",
"aliasNames": [
"Tanjore"
]
},
];
Попытка
searchFilterFunction = text => {
this.setState({
typedText: text
});
const newData = this.arrayholder.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
data: newData
});
};
Комментарии:
1. Я попытался создать фрагмент, но он реагирует и неверен, поэтому я просто отформатировал
2. Если возможно, пожалуйста, предоставьте решение! @mplungjan
3. Нет, дело в том, что у меня есть два отдельных массива, я не мог понять, как объединить оба и получить единый результат
Ответ №1:
Просто пример, я думаю, вы на правильном пути. Я не определял otherIndex, но я думаю, вы поняли идею:
searchFilterFunction = text => {
this.setState({
typedText: text
});
const newData = this.arrayholder.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
const index = itemData.indexOf(textData) > -1
return index ? array2[index] : array1[otherIndex]
});
this.setState({
data: newData
});
};
Комментарии:
1. Но arrayholder содержит только данные array1, у него нет данных array2 (в отдельной переменной)
Ответ №2:
Вы можете добиться этого, не комбинируя их и не выполняя поиск по отдельности. И я предполагаю, что вам нужно показывать псевдоним, если он существует, и показывать имя только тогда, когда псевдоним отсутствует
searchFilterFunction = text => {
this.setState({
typedText: text
});
// Assuming you need to show alias if exists and show name only when alias
// is not present
let newData = this.arrayholder2.find(item => {
const textData = text.toUpperCase();
return itemD.aliasNames.filter(alias =>
alias.toUpperCase().includes(textData)).length > 0;
});
if(newData === undefined) {
// alias does not match, search name now
newData = this.arrayholder1.find(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.includes(textData);
});
}
this.setState({
data: newData
});
};
Комментарии:
1. «Псевдонимы» находятся в разных arrayholder? Я мог бы понять логику, лежащую в основе этих двух реализаций фильтра массива? Можете ли вы это объяснить?
2. Отредактировал свой код, теперь найдите псевдоним, сначала найдя, где в aliasName — массив, поэтому с помощью filter и condition is typedText должно присутствовать имя псевдонима (подстрока)
3. Нет, он не работает, он просто выдает ошибку как неопределенную для «item.name.toUpperCase ()»
4. Пожалуйста, поместите свой пример кода в jsdfiddle или где-нибудь еще и поделитесь ссылкой здесь, чтобы люди могли видеть и помогать
Ответ №3:
В функции сначала создайте объект из массива псевдонимов, где ключ cityName
и значение aliases
.
Теперь, в первом методе фильтрации массива, проверьте text
совпадение как в name
in, так и в соответствующем массиве псевдонимов с помощью some
метода.
const filtered = (data, aliasArr, text) => {
const aliases = {};
aliasArr.forEach(
({ cityName, aliasNames }) => (aliases[cityName] = aliasNames)
);
return data.filter(({ name }) => {
return name.toUpperCase().includes(text.toUpperCase()) ||
aliases[name]?.some((alias) =>
alias.toUpperCase().includes(text.toUpperCase())
);
});
};
const array1 = [
{
id: "117",
name: "Tiruchirapalli",
stateId: "101",
},
{
id: "27110",
name: "Ganoda",
stateId: "1405",
},
{
id: "203",
name: "Tenkasi",
stateId: "101",
},
{
id: "115",
name: "Thanjavur",
stateId: "101",
},
];
const array2 = [
{
id: 1850,
cityName: "Tenkasi",
aliasNames: ["Thenkasi"],
},
{
id: 4521,
cityName: "Tiruchirapalli",
aliasNames: ["Trichy"],
},
{
id: 115,
cityName: "Thanjavur",
aliasNames: ["Tanjore"],
},
];
console.log(filtered(array1, array2, 'Th'))