How can i access this object key in this conditional? - javascript

Write a function countWords that, when given a string as an argument, returns an object where keys are the words in the string, and values are the number of occurrences of that word within the string:
function countWords(string){
string = string.split(" ");
var newObj = {};
for(var i = 0 ; i === newObj.string ; i++){
if(newObj['i'] === newObj[string]){
newObj[string[i]] = i ;
}
}
return newObj;
}
countWords("hello hello"); // => {"hello": 2}
countWords("Hello hello"); // => {"Hello": 1, "hello": 1}
countWords("The quick brown"); // => {"The": 1, "quick": 1, "brown": 1}
I realized since you do not need to count the index of the split string, you have to change the conditions from i < string.length to i === key value of of the objects. Why can't I access the strings with newObj.string?

You could do this with reduce() instead of for loop.
function countWords(string) {
return string.split(' ').reduce(function(r, e) {
r[e] = (r[e] || 0) + 1;
return r;
}, {})
}
console.log(countWords("hello hello"))
console.log(countWords("Hello hello"))
console.log(countWords("The quick brown"))
With for loop your code could go like this.
function countWords(string) {
var string = string.split(" ");
var newObj = {};
for (var i = 0; i < string.length; i++) {
newObj[string[i]] = (newObj[string[i]] || 0) + 1
}
return newObj;
}
console.log(countWords("hello hello"));
console.log(countWords("Hello hello"));
console.log(countWords("The quick brown"));

function countWords(string){
return string
.split(" ")
.reduce((acc, curr) => {
if (curr in acc) {
acc[curr]++
} else {
acc[curr] = 1
}
return acc
}, {})
}
console.log(countWords("hello hello"));
console.log(countWords("Hello hello"));
console.log(countWords("The quick brown"));

You can do it in the following way by using the hasOwnProperty function to check if a property exists in the JavaScript Object, if it does increment the count and if it doesn't then initialize the count to 1.
function countWords(data) {
var words = data.split(" ");
var item = {};
for (var i = 0; i < words.length; i++) {
var prop = words[i];
item.hasOwnProperty(prop) ? item[prop] ++ : item[prop] = 1;
}
console.log(item);
return item;
}
countWords("hello hello"); // => {"hello": 2}
countWords("Hello hello"); // => {"Hello": 1, "hello": 1}
countWords("The quick brown"); // => {"The": 1, "quick": 1, "brown": 1}

newObj[string[i]] = (newObj[string[i]] || 0) + 1
according to my understanding this statement is used to check for duplicity
suppose you crated an empty object and then stored the key value pair in it by using this statement "(newObj[string[i]] || 0) + 1" you are checking if the default value of the key is zero if its zero you then increment its value by 1 if there are multiple value for the same key by doing this you can get the unique value in the array
Example
const uniqueValues = arr => {
let newObj = {}
for (let val of arr){
newObj[val] = [newObj || 0] + 1;
}
return (Object.keys(newObj).length);
}
uniqueValues([1,1,1,1,1,2]);

Related

How to find the longest common prefix in an array of strings?

I'm trying to solve this using the .every method but it's not returning true and therefore it's not adding onto my string and I'm not sure why.
var longestCommonPrefix = function(arr) {
if (arr.length === 0) {
return undefined;
}
let result = '';
for (let i = 0; i < arr.length; i++) {
if (arr.every(x => arr[i].charAt(i) === x)) {
result += arr[i].charAt(i);
}
}
return result
}
console.log(longestCommonPrefix(["flower", "flow", "flight"])); //fl
You need to iterate over one string, not over the whole array: check if the first character of the string is present everywhere, then the second character, etc:
var longestCommonPrefix = function(arr) {
if (arr.length === 0) {
return undefined;
}
let result = '';
for (let i = 0; i < arr[0].length; i++) {
if (arr.every(x => x.charAt(i) === arr[0][i])) {
result += arr[i].charAt(i);
} else break;
}
return result;
}
console.log(longestCommonPrefix(["flower", "flow", "flight"])); //fl
Your use of Array.every is along the right lines. You want to check that every string in the array has the same character at position i. I think you got confused when you named the parameter x, when it is in fact a string :)
var longestCommonPrefix = function(words) {
if (words.length === 0) {
return "";
}
const letters = [];
const lengthOfShortestWord = Math.min(...words.map(word => word.length));
for (let i = 0; i < lengthOfShortestWord; i++) {
const char = words[0][i];
if (words.every(word => word[i] === char)) {
letters.push(char);
} else {
break;
}
}
return letters.join("");
}
console.log(longestCommonPrefix(["flower", "flow", "flight"])); //fl
Unless I am mistaken the longest prefix is never going to be greater than the smallest string in the array.
In this case "fl" is both the smallest string and the longest common prefix:
["flower", "fl", "flight"]
So start with finding the smallest string in arr:
let [sm] = [...arr].sort((a, b) => a.length - b.length);
Then check that all strings in arr start with sm:
arr.every(str => str.startsWith(sm));
If that isn't the case then shorten sm by one character:
sm = sm.slice(0, -1);
And keep going until you eventually find the longest prefix or sm becomes an empty string:
const prefix = arr => {
let [sm] = [...arr].sort((a, b) => a.length - b.length);
while (sm && !arr.every(str => str.startsWith(sm))) sm = sm.slice(0, -1);
return sm;
};

How to collapse an array by joining all strings, but leaving objects

While I'm sure I'm waay over-complicating things, I'm curious to know how I would "collapse" an array by combining all adjacent strings, but leaving objects as objects so that:
array = ["I","want","to",[Obj],"come","together"]
outputs
["I want to", [Obj], "come together"];
I feel like array.reduce() might be the ticket here, but I'm still wrapping my head around that function.
Reduce the array. If the current item and the last item in the accumulator (r) are strings, concatenate them. If not, push the current item to the accumulator:
const array = ["I","want","to",[{}],"come","together"]
const isString = s => typeof s === 'string'
const result = array.reduce((r, o) => {
if(isString(o) && isString(r[r.length - 1])) {
r[r.length - 1] = `${r[r.length - 1]} ${o}`
} else {
r.push(o)
}
return r
}, [])
console.log(result)
I would do this:
const array = ["I","want","to",{},"come","together"];
let outputArr = [];
let strArr = [];
array.forEach(elem => {
if (typeof elem === 'string') {
return strArr.push(elem);
}
outputArr.push(strArr.join(' '));
strArr = [];
outputArr.push(elem);
});
outputArr.push(strArr.join(' '));
console.log(outputArr);
In case you wanna go with the plain old for-loop :)
var result = [], array = ["I","want","to",{a: 1, b:2},"come","together"];
var i=0;var str = "";
for(; i< array.length; i++){
if(typeof array[i] === 'object' ){
result.push(str);
result.push(array[i]);
str="";
}else{
str = str+" "+ array[i];
}
}
if(i==array.length){
result.push(str);
}
console.log(result);

How do I write a function that takes an array of values and returns an object

in this format; sample input: ["book", 1, "table", 4] sample output: { string: ["book", "table"], number: [1,4] }
here is the code i have written but it's not giving me the output i want.
function listDic(arr) {
if (Array.isArray(arr)) {
let output = {};
for (let i =0; i == arr.length; i++) {
if (typeof arr[i] === 'string') {
var str = [];
str.push(arr[i]);
}
if (typeof arr[i] === 'number') {
var num = [];
num.push(arr[i]);
}
}
return {string: str, number: num}
}
return "Only arrays are allowed.";
}
please what exactly am i getting wrong?
You could use the type directly as key for the object, while iterating the array.
If you have not an object with the key, generate a new one with an empty array for pushing the actual item.
var array = ["book", 1, "table", 4],
object = {};
array.forEach(function (a) {
var type = typeof a;
object[type] = object[type] || [];
object[type].push(a);
});
console.log(object);
You're overwriting str and num in the loop without ever keeping any other reference to the arrays. Put those arrays in the output object, and then push into those.
var data = ["book", 1, "table", 4];
console.log(listDic(data));
function listDic(arr) {
if (!Array.isArray(arr)) {
return "Only arrays are allowed.";
}
let output = {
string: [],
number: []
};
for (let i = 0; i < arr.length; i++) {
switch (typeof arr[i]) {
case "string":
output.string.push(arr[i]);
break;
case 'number':
output.number.push(arr[i]);
}
}
return output;
}
You could just reduce the array into an object, and use the type of the values as keys
var arr = ["book", 1, "table", 4];
function listDic(arr) {
return arr.reduce((a, b) => {
let t = typeof b;
a[t] ? a[t].push(b) : a[t] = [b];
return a;
}, {});
}
console.log(listDic(arr));
thanks i got a better way to solve it myself
function listDic(arr) {
if (Array.isArray(arr)) {
let str = [];
let num = [];
for (let i =0; i < arr.length; i++) {
if (typeof arr[i] === 'string') {
str.push(arr[i]);
}
if (typeof arr[i] === 'number') {
num.push(arr[i]);
}
}
return {string: str, number: num}
}
return "Only arrays are allowed.";
}
I think this should work for you :
function listDic(arr) {
if (Array.isArray(arr)) {
let output = {};
var str = [],
num = []; //CORRECTED
for (let i = 0; i < arr.length; i++) { //CORRECTED
if (typeof arr[i] === 'string') {
str.push(arr[i]);
}
if (typeof arr[i] === 'number') {
num.push(arr[i]);
}
}
return { string: str, number: num }
}
return "Only arrays are allowed.";
}
console.log(listDic(["book", 1, "table", 4]));
Explanation
Basically, there were two issues:
you were really not entering the loop with == arr.length on your for-loop's entry condition.
you kept re-assigning the str and num arrays with a re-declaration var str[i] = [] OR var num[i] = [].
Hope this helps.

How can I count characters in an JavaScript array?

I need to count the characters from a to z in an array.
For example I have an array like this:
["max","mona"]
The desired result would be something like this:
a=2, m=2, n=1, o=1, x=1
It would be great, if anyone could help me :)
You can use two forEach loops and return object
var ar = ["max", "mona"], o = {}
ar.forEach(function(w) {
w.split('').forEach(function(e) {
return o[e] = (o[e] || 0) + 1;
});
});
console.log(o)
Or with ES6 you can use arrow function
var ar = ["max","mona"], o = {}
ar.forEach(w => w.split('').forEach(e => o[e] = (o[e] || 0)+1));
console.log(o)
As #Alex.S suggested you can first use join() to return string, then split() to return array and then you can also use reduce() and return object.
var ar = ["max", "mona"];
var result = ar.join('').split('').reduce(function(o, e) {
return o[e] = (o[e] || 0) + 1, o
}, {});
console.log(result)
You can use just one forEach loop and return object
var ar = [ "bonjour", "coucou"], map = {};
ar.join("").split("").forEach(e => map[e] = (map[e] || 0)+1);
console.log(map);
Live Demo
https://repl.it/C17p
I would do it like this;
var a = ["max","mona"],
charCount = a.reduce((p,w) => w.split("").reduce((t,c) => (t[c] ? t[c]++: t[c] = 1,t),p),{});
console.log(charCount);
public static void main (String[] args) throws java.lang.Exception
{
String[] original = {"The","Quick","Brown","Fox","Jumps","Over","The","Lazy","Dog"};
String singleString ="";
for(String str : original )
{
singleString += str;
}
System.out.println(singleString);
char[] chars = singleString.toLowerCase().toCharArray();
Arrays.sort(chars);
String result="";
for(int i=0;i<chars.length;)
{
result += chars[i]+"=";
int count=0;
do {
count++;
i++;
} while (i<chars.length-1 && chars[i-1]==chars[i]);
result += Integer.toString(count)+",";
}
System.out.println(result.substring(0,result.length()-1));
}
The solution using Array.join, Array.sort and String.split functions:
var arr = ["max","mona"],
counts = {};
arr = arr.join("").split(""); // transforms the initial array into array of single characters
arr.sort();
arr.forEach((v) => (counts[v] = (counts[v])? ++counts[v] : 1));
console.log(counts); // {a: 2, m: 2, n: 1, o: 1, x: 1}
Try this:
var words = ['max', 'mona'],
output = {};
words.forEach(function(word){
for(i=0; i < word.split('').length; i++){
if(output[word[i]])
output[word[i]] += 1;
else{
output[word[i]] = 1;
}
}
});
ps: sorry for the code not being formatted, I'm still getting used to the editor =)

String split and count the number of occurrences and also

I have a string
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$";
How to get the count of the number of occurrences of each entry, The occurrence I get, is from a JSON like Java = 8 and etc...
First of all you need to split your srting to array:
var keywordsArr = stringIHave.split( '$$' );
then you need to have an object for example to store counts:
var occur = {};
and then just create simple for loop to count all occurrences:
for( var i = 0; i < keywordsArr.length; i++ ) {
occur[ keywordsArr[ i ] ] = ( occur[ keywordsArr[ i ] ] || 0 ) + 1;
}
now your object occur will have names as keys and count as values.
See jsFiddle demo.
Also as you have at end of your string $$ you maybe will need to remove last item from keywordsArr so just do after split function call:
keywordsArr.pop();
See demo without last element.
So final code will be like:
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$",
keywordsArr = stringIHave.split( '$$' ),
occur = {};
keywordsArr.pop();
for( var i = 0; i < keywordsArr.length; i++ ) {
occur[ keywordsArr[ i ] ] = ( occur[ keywordsArr[ i ] ] || 0 ) + 1;
}
for( var key in occur ) {
document.write( key + ' - ' + occur[key] + '<br/>' );
} ​
I'd suggest the following:
function stringCount(haystack, needle) {
if (!needle || !haystack) {
return false;
}
else {
var words = haystack.split(needle),
count = {};
for (var i = 0, len = words.length; i < len; i++) {
if (count.hasOwnProperty(words[i])) {
count[words[i]] = parseInt(count[words[i]], 10) + 1;
}
else {
count[words[i]] = 1;
}
}
return count;
}
}
console.log(stringCount("Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$", '$$'));
​
JS Fiddle demo.
References:
Object.hasOwnProperty().
parseInt().
String.split().
It's not entirely clear what final objective is. Following creates an object from string that looks like
Object created:
{
"Java": 8,
"jQuery": 4,
"Hibernate": 1,
"Spring": 1,
"Instagram": 1
}
JS:
var str = 'Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$';
var arr = str.split('$$')
var obj = {};
for (i = 0; i < arr.length; i++) {
if (arr[i] != '') {
if (!obj[arr[i]]) {
obj[arr[i]] = 0;
}
obj[arr[i]]++;
}
}
You can loop over the object to get all values or simply look up one value
var jQueryOccurences= obj['jQuery'];
DEMO: http://jsfiddle.net/25hBV/1/
Now a days you can do
const str = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$";
var result = str.split("$$").reduce(function(acc, curr) {
curr && (acc[curr] = (acc[curr] + 1) || 1);
return acc
}, {});
console.log(result);
Split the string into an array, and putting the array into an object takes care of duplicates and counts occurences as key/value pairs in the object, see fiddle!
var stringIHave = "Java$$Java$$jQuery$$Java$$jQuery$$Java$$Java$$Java$$Hibernate$$Java$$Java$$Spring$$Instagram$$jQuery$$jQuery$$",
s = stringIHave.split('$$');
obj = {};
for (var i=s.length; i--;) {
obj[s[i]] = (s[i] in obj) ? obj[s[i]]+1 : 1;
}
// obj.Java == 8
FIDDLE
If you want it short and sweet:
// variable declarations
var arParts = stringIHave.match(/\w+/g),
result = {},
i = 0,
item;
// Copy the array to result object
while (item = arParts[i++]) result[item] = (result[item] || 0 ) + 1;
demo

Categories

Resources