#javascript #jquery #local-storage
#javascript #jquery #локальное хранилище
Вопрос:
Я пытаюсь понять, как чего-то добиться. У меня есть тип карты, на которой вы можете щелкнуть по стране и ввести некоторые данные. Когда данные отправляются, я сохраняю их в локальном хранилище
$('#question-form').on('submit', function(e){
e.preventDefault();
let country = $('#hidden-input').val();
let questionOne = $('#questionOne').val();
let questionTwo = $('#questionTwo').val();
let clientObj = {
country : country,
questionOne : questionOne,
questionTwo: questionTwo
};
let clientsArr = [];
if(!localStorage.getItem('Countries')) {
clientsArr.push(clientObj);
localStorage.setItem('Countries', JSON.stringify(clientsArr));
} else {
clientsArr = JSON.parse(localStorage.getItem('Countries'));
clientsArr.push(clientObj);
localStorage.setItem('Countries', JSON.stringify(clientsArr));
}
$('#myModal').modal('hide');
});
Через некоторое время мое локальное хранилище заполняется данными, которые принимают следующую форму
[{country: "United Kingdom", questionOne: "test", questionTwo: "test"},…]
0: {country: "United Kingdom", questionOne: "test", questionTwo: "test"}
1: {country: "Ireland", questionOne: "test 2", questionTwo: "test 2"}
2: {country: "Iran", questionOne: "Test 3", questionTwo: "Test 3"}
3: {country: "United Kingdom", questionOne: "Test 4", questionTwo: "Test 4"}
То, что я пытаюсь сделать, это отобразить эти результаты. Итак, на моей странице у меня есть несколько заполнителей
<div id="display">
<div id="country-name"></div>
<div class="question-one-data"></div>
<div class="question-two-data"></div>
</div>
Затем я дошел до этого момента
if (!localStorage.getItem('Countries')) {
$('#display').html('<p>No results to display</p>');
} else {
console.log(JSON.stringify(localStorage.getItem('Countries')))
}
Поэтому, если данных нет, это сообщит пользователю. Это в другом, я немного застрял. Теперь отображение данных не является проблемой. С чем я борюсь, так это с фильтрацией. Поэтому я хочу, чтобы для страны был установлен заполнитель имени страны,
однако он должен отображать страну только один раз. Поэтому мне, по сути, нужно фильтровать мои результаты по странам. В моем примере вы можете видеть, что для Соединенного Королевства было две записи, поэтому результат, который я ищу, это
<div id="display">
<div id="country-name">United Kingdom</div>
<div class="question-one-data">test</div>
<div class="question-two-data">test</div>
<hr>
<div class="question-one-data">Test 4</div>
<div class="question-two-data">Test 4</div>
<hr>
<div id="country-name">Ireland</div>
<div class="question-one-data">test 2</div>
<div class="question-two-data">test 2</div>
...
</div>
Как бы мне отфильтровать свои данные по названию страны, а затем получить структуру, как показано выше?
Спасибо
Комментарии:
1. Вы имеете в виду, что хотите исправить свои данные, чтобы каждый объект
countryName
с определенным значением встречался в массиве только один раз?
Ответ №1:
Допустим, у вас есть ваши данные в переменной с именем answers
. Вы можете создать список всех уникальных названий стран с помощью:
const countries = Array.from(new Set(answers.map(a => a.country)))
Затем вы можете изменить свои данные и сохранить все ответы для данной страны в новом массиве:
const countriesWithAnswers = countries.map(countryName => ({
name: countryName,
answers: answers
.filter(answer => answer.country === countryName)
.map(({ questionOne, questionTwo }) => ({ questionOne, questionTwo }))
}))
Чтобы отобразить данные, вы можете выполнить итерацию по answers
массиву для каждого элемента countriesWithAnswers
.
Ответ №2:
Если я правильно понимаю вашу задачу, вот мое предполагаемое решение
Сначала вам нужно отсортировать массив по названию страны:
countriesArray = [
{country: "United Kingdom", questionOne: "test", questionTwo: "test"},
{country: "Ireland", questionOne: "test 2", questionTwo: "test 2"},
{country: "Iran", questionOne: "Test 3", questionTwo: "Test 3"},
{country: "United Kingdom", questionOne: "Test 4", questionTwo: "Test 4"}
...
]
countriesArray.sort((a, b) => {
if (a.country < b.country) return -1
if (a.country > b.country) return 1
return 0
})
Затем вы можете выполнить итерацию по нему, чтобы собрать все данные, определенные для конкретного названия страны:
let currentCountry
const results = {}
for (const item of countriesArray) {
const { country, questionOne, questionTwo } = item;
if (currentCountry === undefined || currentCountry !== country) {
currentCountry = country
}
if (!results[currentCountry]) {
results[currentCountry] = []
}
results[currentCountry].push({
questionOne,
questionTwo,
})
}
После этого вы можете снова выполнить итерацию по нему и отобразить некоторый HTML.
Надеюсь, это решит вашу проблему 👌
Ответ №3:
ваш исходный массив стран
let countries =[
{country: "United Kingdom", questionOne: "test", questionTwo: "test"},
{country: "Ireland", questionOne: "test 2", questionTwo: "test 2"},
{country: "Iran", questionOne: "Test 3", questionTwo: "Test 3"},
{country: "United Kingdom", questionOne: "Test 4", questionTwo: "Test 4"}
];
объявите переменную с именем sortedCountries . выполните итерацию по массиву стран и для каждой страны проверьте, не существует ли название страны в отсортированном массиве. затем вставьте его в отсортированный массив.
let sortedCountries = [];
countries.forEach(country => {
if (!sortedCountries.some(el => el.country === country.country)) {
sorted.push(country)
};
})
Ответ №4:
Создайте список уникальных стран с помощью Set
объекта. Этот объект может содержать коллекцию значений с условием, что каждое значение уникально, что упрощает фильтрацию дубликатов. Превращение набора обратно в массив позволяет использовать его для дальнейшего зацикливания и манипулирования.
Затем перебирайте каждое название страны с Array.prototype.map()
помощью и используйте Array.prototype.find()
, чтобы найти первое вхождение названия страны в массиве, с которым вы работаете. Это создаст новый массив с объектами, которые ранее не встречались.
const questions = [
{
country: "United Kingdom",
questionOne: "test",
questionTwo: "test"
},
{
country: "Ireland",
questionOne: "test 2",
questionTwo: "test 2"
},
{
country: "Iran",
questionOne: "Test 3",
questionTwo: "Test 3"
},
{
country: "United Kingdom",
questionOne: "Test 4",
questionTwo: "Test 4"
}
];
const filterQuestions = questions => {
const uniqueCountries = Array.from(new Set(
questions.map(({ country }) => country))
);
return uniqueCountries.map(country =>
questions.find(question => question.country === country)
);
}
const uniqueQuestions = filterQuestions(questions);
console.log(uniqueQuestions);