У меня есть очень большой массив слов в массиве, и я хочу рассчитать их все и добавить количество в качестве значения для каждой строки.
Поэтому я, например:
words = ["a", "hello", "hello", "b", "went", "a"]
Я хочу преобразовать это в:
words = [{"a" => 2}, {"b" => 1}, {"hello" => 2}, {"went" => 1}]
Я видел способы просто пересчитать одно слово в строке и вернуть свои вхождения, но как я могу сделать это в больших масштабах, создав массив хэшей с количеством вхождений?
Я могу удалить повторяющиеся значения после, меня больше интересует процесс подсчета значений и добавления значения count в хэш.
В первую очередь вы можете создать объект со значением массива и числом вхождения. Затем пропустите его, чтобы создать массив объектов
var words = ["a", "hello", "hello", "b", "went", "a"];
var rObj = {};
var finalArray = [];
words.map(function(currentValue, index) {
if (rObj.hasOwnProperty(currentValue)) {
rObj[currentValue] = rObj[currentValue] + 1;
} else {
rObj[currentValue] = 1
}
});
for (var keys in rObj) {
var obj = {};
obj[keys] = rObj[keys];
finalArray.push(obj)
};
console.log(finalArray)
Для действительно огромного массива я предлагаю использовать какое-либо while
цикла for
и обычную проверку, существует ли ключ со словом. Если не назначить ему нуль. Позже добавьте свойство объекта count.
Наконец, преобразование объекта в массив с требуемой структурой.
var words = ["a", "hello", "hello", "b", "went", "a"],
w,
i = words.length,
count = Object.create(null),
result;
while (i--) {
w = words[i];
if (!count[w]) {
count[w] = 0;
}
count[w]++;
}
result = Object.keys(count).map(function (k) {
var temp = {};
temp[k] = count[k];
return temp;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Сначала вы можете использовать reduce()
для подсчета элементов и возврата объекта, а затем map()
для возврата массива значений объекта.
var words = ["a", "hello", "hello", "b", "went", "a"]
var count = words.reduce(function(r, e) {
if(!r[e]) r[e] = {[e]: 1}
else r[e][e] += 1
return r;
}, {})
var result = Object.keys(count).map(e => count[e])
console.log(result)
reduce
это хороший выбор. Хотя в зависимости от того, насколько «массивен» массив, вы можете реализовать это с помощью цикла for
.
(r[e] ? r[e] += 1 : r[e] = 1); return r;
внутри слова. words.reduce
? Это спасло бы вызов map
. Или я здесь не прав?
Не считайте повторителей хэшированием. Используйте цикл while для небольших накладных расходов. Задания для расчета. Вы получите ответ на порядок в 5 раз быстрее. Один миллион слов, случайно генерируемых из 12 слов в 1/5 раз.
var wordsArray = ['apple', 'beer', 'cake', 'potato', 'orange', 'monitor', 'program', 'application', 'keyboard', 'javascript', 'gaming', 'network'],
words = [];
for (i = 0; i < 1000000; i++) {
words.push(wordsArray[Math.floor(Math.random() * wordsArray.length)]);
}
function getCount(words) {
var w,
i = words.length,
hash = {};
while (i--) {
w = words[i];
if (!hash[w]) {
hash[w] = 0;
}
hash[w]++;
}
return hash
}
console.time('Obj-time');
var counts = getCount(words);
array = [];
for (let i in counts) {
var l = i.length,
val = counts[i];
array.push({
[i]: val * l
})
}
console.log(array);
console.timeEnd('Obj-time');
Map
может иметь любой тип ключа.