I've found a solution that gives the correct result when the word is at the same index, within each of the array elements, but in the case below, the term/word searched can be anywhere in the element (beginning or end).
array =
[
["A"], ["earth"], ["20"], ["tunnel"],
["house"], ["earth A"], ["$100"], ["house $100"]
]
Expected result:
result =
[
["A", 2], ["earth", 2], ["20", 1], ["tunnel", 1],
["house", 2], ["earth A", 1], ["$100", 2], ["house $100", 1],
]
Here's the attempt using the solution above:
array = [
["A"],
["earth"],
["20"],
["tunnel"],
["house"],
["earth A"],
["$100"],
["house $100"]
];
function count(array) {
return array.reduce((acc, arr) => {
for (const item of arr) {
acc[item] = acc[item] !== undefined ? acc[item] 1 : 1
}
return acc
}, {})
}
console.log(count(array))
Appreciate your help!
CodePudding user response:
So: basically the same as Louys Patrice Bessette's answer but instead of setting the value of the object prop to the current count it assigns an array (word and count) to the value instead, and then updates the count at index 1. Wrapping the operation in Object.values
will return only those arrays (as an array).
const data=[["A"],["earth"],["20"],["tunnel"],["house"],["earth A"],["$100"],["house $100"]];
const out = Object.values(data
.flat()
.join(' ')
.split(' ')
.reduce((acc, word) => {
acc[word] ??= [ word, 0 ];
acc[word][1];
return acc;
}, {})
);
console.log(JSON.stringify(out));
Additional documentation
CodePudding user response:
I would flatten the array... Then join the array elements by the spaces to split by the spaces.
That will give an array of words.
Then use reduce to count them.
const array = [
["A"],
["earth"],
["20"],
["tunnel"],
["house"],
["earth A"],
["$100"],
["house $100"]
];
function count(array) {
return array.flat().join(" ").split(" ")
.reduce((acc, word) => {
acc[word] = acc[word] !== undefined ? acc[word] 1 : 1
return acc
}, {})
}
// call the count function
const result = count(array)
// Console log each values
for (const key in result){
console.log(`The word "${key}" was found ${result[key]} time${result[key] > 1 ? 's' : ''}.`)
}
CodePudding user response:
If you need to support any amount of nested arrays and get EXACT REQUESTED output format, check inline comments:
// Array
array = [
["A", "B", ["B", "B B"]],
["earth"],
["20"],
["tunnel"],
["house"],
["earth A"],
["$100"],
["house $100"]
];
// Count function
const count = array => {
// Counter holder
const counter = {};
// Recursive function
const rf = function rf(arr) {
for(const i of arr) {
// If item is array, count recursively
// and skip current cycle
if(Array.isArray(i)) { rf(i); continue; }
// Split string
const iArr = i.split(" ");
// If array has more then 1 items, count
// recursively and keep current cycle, as
// you need to capture and count the
// whole words group to
if(iArr.length > 1) rf(iArr);
// Put word/group in object with value 1
// If word/group exist, increase counter
counter[i] ? counter[i] : counter[i] = 1;
}
}(array);
// Return counter
return counter;
}
// Do count
const counter = count(array);
// Result comes in object form
console.log(counter);
// But you can format result as you needed
console.log(JSON.stringify(Object.keys(counter).map(key => [key, counter[key]])));
CodePudding user response:
Word Count on a sheet:
function wordcount() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
sh.clearContents();
const a = [["A"], ["earth"], ["20"], ["tunnel"], ["house"], ["earth A"], ["$100"], ["house $100"]];
sh.getRange(1, 1, a.length, a[0].length).setValues(a);
let o = [... new Set(a.slice().flat().join(' ').split(' '))].map(w => [w, sh.createTextFinder(w).matchCase(true).findAll().length]);
o.unshift(["Words","Count"]);
sh.getRange(sh.getLastRow() 2,1,o.length,o[0].length).setValues(o);
}
Original | |
---|---|
A | |
earth | |
20 | |
tunnel | |
house | |
earth A | |
$100 | |
house $100 | |
Words | Count |
A | 2 |
earth | 2 |
20 | 1 |
tunnel | 1 |
house | 2 |
$100 | 2 |
CodePudding user response:
Use String.includes after Array.flat:
/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
const array = [
['A'],
['earth'],
['20'],
['tunnel'],
['house'],
['earth A'],
['$100'],
['house $100'],
],
arrayFlat = array.flat(),
counts = array.map(([e]) => [
e,
arrayFlat.reduce((a, c) => a String(c).includes(e), 0),
]);
console.table(counts);
<!-- https://meta.stackoverflow.com/a/375985/ --> <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>