show object template angular which counts the number of repeated words - javascript

I want to show the Object wordCounts,which stores a series of words with a value that is the number of times a word is repeated in a string, what happens is that I want to show that variable in order by the number of repetitions that word has, and I just want the 20 most repeated words to be shown. The main problem I have is that as far as I have the code it returns a JSON, which does not allow me to put in a div to give it a style.
project-details.ts
getWordCount(str) {
let arrayOfWords = str.split(/\s+/);
var wordCounts = Object.create(null);
for(let i = 0; i<arrayOfWords.length; i++){
let word = arrayOfWords[i];
if(!wordCounts[word]){
wordCounts[word] = 1;
}else{
wordCounts[word] ++;
}
}
return wordCounts;
};
project-details.html
<p>{{getWordCount(str) | keyvalue | json}}</p>
representation
[ { "key": "También", "value": 1 }, { "key": "Un", "value": 1 }, { "key": "algoritmo", "value": 1 }, { "key": "aunque", "value": 1 }, { "key": "caracteres", "value": 1 }, { "key": "cifrado", "value": 1 }, { "key": "codificados", "value": 1 }, { "key": "composición", "value": 2 }, { "key": "cualquier", "value": 1 }, { "key": "de", "value": 5 }, { "key": "descifrado", "value": 1 }, { "key": "destinatario", "value": 1 }, { "key": "en", "value": 1 }, { "key": "es", "value": 2 }, { "key": "escritura", "value": 1 }, { "key": "forma", "value": 1 }, { "key": "generados", "value": 1 }, { "key": "imprimibles", "value": 1 }, { "key": "no", "value": 1 }, { "key": "original.", "value": 1 }, { "key": "para", "value": 1 }, { "key": "persona,", "value": 1 }, { "key": "por", "value": 2 }, { "key": "puede", "value": 1 }, { "key": "que", "value": 1 }, { "key": "que,", "value": 1 }, { "key": "sentido", "value": 1 }, { "key": "sentido.", "value": 1 }, { "key": "ser", "value": 1 }, { "key": "signos", "value": 1 }, { "key": "sistema", "value": 1 }, { "key": "su", "value": 1 }, { "key": "sí", "value": 1 }, { "key": "texto", "value": 1 }, { "key": "tienen", "value": 1 }, { "key": "un", "value": 2 }, { "key": "una", "value": 3 }, { "key": "unidad", "value": 1 } ]
And with that result I can't give it any style.

You could assign the value to a variable, remove the json pipe and loop the value directly in the HTML. Try the following
Controller
export class WordComponent {
wordCount: any;
getWordCount(str) {
let arrayOfWords = str.split(/\s+/);
let wordCounts = Object.create(null);
for(let i = 0; i < arrayOfWords.length - 1; i++){
let word = arrayOfWords[i];
wordCounts[word] ? wordCounts[word]++ : wordCounts[word] = 1;
}
return wordCounts;
};
onMouseUp(str: string) {
this.wordCount = this.getWordCount(str);
}
}
Template
<button (mouseup)="onMouseUp('str')">Get word count</button>
<ng-container *ngIf="wordCount">
<p class="style" *ngFor="let word of wordCount | keyvalue">{{ word.key }} : {{ word.value }}</p>
</ng-container>
You can then modify and render as per you wish. Also note the loop condition should be arrayOfWords.length - 1 because index starts from zero.

It sounds like what you need is a ShowWordCounts component which takes your object as an #Input and generates the corresponding template.

Related

Compare value to get largest number in every object looping JavaScript

I have a problem with how to compare value to get largest number in more than one object.
For example i have 3 object (and this object can increment more than 3):
These each object saved in acc variable
[
{ "key": 1, "value": 1 },
{ "key": 1, "value": 3 },
{ "key": 1, "value": 6 },
]
[
{ "key": 2, "value": 2 },
{ "key": 2, "value": 5 },
{ "key": 2, "value": 9 },
]
[
{ "key": 3, "value": 1 },
{ "key": 3, "value": 2 },
{ "key": 3, "value": 3 },
]
First i get the last value from each object with console.log(acc[acc.length - 1].value);
and it will print:
6
9
2
Then i don't know how to compare the numbers? And get result:
{ "key": 2, "value": 9 }
I have try console.log(Math.max(acc[acc.length - 1].value));, but its not working because that number is not inside one array.
This is screenshot if i log console.log(acc)
First merge all the nested objects by .flat() and perform .reduce() operation on them. in every iteration look b.value is greater than the object value of accumulator a.value, if it's the case we need to update the object of the accumulator a.
const arr = [[ { "key": 1, "value": 1 }, { "key": 1, "value": 3 }, { "key": 1, "value": 6 }, ], [ { "key": 2, "value": 2 }, { "key": 2, "value": 5 }, { "key": 2, "value": 9 }, ], [ { "key": 3, "value": 1 }, { "key": 3, "value": 2 }, { "key": 3, "value": 3 }, ]];
console.log(arr.flat().reduce((a,b)=>(b.value > a.value ? b : a)));
New requirement:
const arr = [[
{ "key": 1, "value": 1 },
{ "key": 1, "value": 3 },
{ "key": 1, "value": 6 },
{ "key": 3, "value": 6 },
],
[
{ "key": 2, "value": 2 },
{ "key": 2, "value": 5 },
{ "key": 2, "value": 9 },
],
[
{ "key": 3, "value": 1 },
{ "key": 3, "value": 2 },
{ "key": 3, "value": 3 },
]];
let results = [{key: -1, value: -1}]; //initial value I assume data don't have a value less than -1
arr.forEach((item) => { //Simulating your current situation
item.forEach(it => { //here we get an array in each iteration
if (it.value > results[0].value) {
results = [it];
}
else if (it.value === results[0].value) {
results.push(it);
}
});
});
console.log(results);

filter nested array with Javascript

having an array with objects and inside an options array how do I filter the inner array of objects by key value?
Here is the following example:
let test = [{
"options": [{
"label": "Audi",
"value": 10
},
{
"label": "BMW",
"value": 18
},
{
"label": "Mercedes Benz",
"value": 116
},
{
"label": "VW",
"value": 184
}
],
"label": "test1"
},
{
"options": [{
"label": "Adler",
"value": 3664
},
{
"label": "Alfa Romeo",
"value": 3
},
{
"label": "Alpine",
"value": 4
}
],
"label": "test2"
}
]
how do I get back the object:
{
"label": "Audi",
"value": 10
}
if I filter with keyword Audi
return label.toLowerCase().includes(inputValue.toLowerCase());
I tried with the following
test.map((k) => {
res = k.options.filter((j) => {
inputValue.toLowerCase();
if (j.label.toLowerCase().includes(inputValue.toLowerCase())) {
return j;
}
});
});
You need to return the result of filter(), not just assign it to a variable, so that map() will return the results.
let test = [{
"options": [{
"label": "Audi",
"value": 10
},
{
"label": "BMW",
"value": 18
},
{
"label": "Mercedes Benz",
"value": 116
},
{
"label": "VW",
"value": 184
}
],
"label": "test1"
},
{
"options": [{
"label": "Adler",
"value": 3664
},
{
"label": "Alfa Romeo",
"value": 3
},
{
"label": "Alpine",
"value": 4
}
],
"label": "test2"
}
]
let inputValue = "audi";
let search = inputValue.toLowerCase();
let result = test.map(k => k.options.filter(j => j.label.toLowerCase().includes(search)));
console.log(result);
This will return all options matching the search query :
function find(array, query) {
return array.reduce((prev, current) => prev.concat(current.options), []).filter(item => item.label.includes(query))
}
find(test, 'Audi')
Use flatMap() followed by filter():
let test=[{options:[{label:"Audi",value:10},{label:"BMW",value:18},{label:"Mercedes Benz",value:116},{label:"VW",value:184}],label:"test1"},{options:[{label:"Adler",value:3664},{label:"Alfa Romeo",value:3},{label:"Alpine",value:4}],label:"test2"}]
let result = test.flatMap(el => {
return el.options.filter(car => car.label == "Audi")
})[0]
console.log(result)
You need to go two levels deep when traversing your array.
function filterArray(needle, haystack) {
return haystack
.map(h => h.options)
.flatMap(h => h )
.filter(h => h.label.toLowerCase().includes(needle.toLowerCase()));
CodeSandbox
This might gile your answer:
console.log(test[0].options[0]);

Swimlane ngx-charts in Angular2 - Different styles on a single line chart

I have a single line chart, with dates on the X axis. After a certain date,
I would like the line to be a different color. Is this possible using ngx-charts?
Let us assume the date after which you want to change the color as T.
Now you can divide the series into 2 parts
The from start date to T
From T to end date.
And now you can plot the graph using different color for different series
The following data will generate the desired graph.
var data = [
{
"name": "Current",
"series": [
{
"value": 5599,
"name": "2016-09-20T01:04:28.176Z"
},
{
"value": 6247,
"name": "2016-09-20T12:51:24.713Z"
},
{
"value": 4283,
"name": "2016-09-18T15:42:04.800Z"
},
{
"value": 2643,
"name": "2016-09-13T20:10:53.904Z"
},
{
"value": 4105,
"name": "2016-09-18T06:15:10.845Z"
},
{
"name": "2016-09-18T13:08:42.085Z",
"value": 4401
},
{
"name": "2016-09-20T01:04:28.176Z",
"value": 3443
}
]
},
{
"name": "Future",
"series": [
{
"value": 3443,
"name": "2016-09-20T01:04:28.176Z"
},
{
"value": 2604,
"name": "2016-09-20T12:51:24.713Z"
},
{
"value": 2158,
"name": "2016-09-18T15:42:04.800Z"
},
{
"value": 5519,
"name": "2016-09-13T20:10:53.904Z"
},
{
"value": 4532,
"name": "2016-09-18T06:15:10.845Z"
},
{
"name": "2016-09-18T13:08:42.085Z",
"value": 2474
}
]
}
]

transforming json using recursive function

I'm trying to transform this JSON into array so that I can simply list them as key-value pairs in html. The JSON has nested properties which I want to retain but I want to stringify only those objects that contain "units" and "value". All others should be listed as children items. Please help figure what I'm doing wrong.
Here's the json input:
{
"clusterName": "ml6.engrlab.com-cluster",
"statusProperties": {
"loadProperties": {
"loadDetail": {
"restoreWriteLoad": {
"value": 0,
"units": "sec/sec"
},
},
"totalLoad": {
"value": 0.0825921967625618,
"units": "sec/sec"
}
},
"secure": {
"value": false,
"units": "bool"
},
"statusDetail": {
"licenseKeyOption": [
{
"value": "conversion",
"units": "enum"
},
{
"value": "failover",
"units": "enum"
}
],
"connectPort": 7999,
"softwareVersion": {
"value": 9000100,
"units": "quantity"
}
},
"rateProperties": {
"rateDetail": {
"largeReadRate": {
"value": 0,
"units": "MB/sec"
}
},
"totalRate": {
"value": 67.2446365356445,
"units": "MB/sec"
}
},
"online": {
"value": true,
"units": "bool"
},
"cacheProperties": {
"cacheDetail": {
"tripleCachePartitions": {
"tripleCachePartition": [
{
"partitionSize": 768,
"partitionBusy": 0,
"partitionUsed": 0,
"partitionFree": 100
}
]
}
}
}
}
}
my code
function isNested(obj) {
if(!obj) return false;
let propArry = Object.keys(obj)
for(let i=0; i<propArry.length; i++){
if(obj[propArry[0]].constructor.name === 'Object') return true
}
return false;
}
function getKeyValueAsChildren(obj) {
let vals = [];
for(let key in obj) {
if(obj.hasOwnProperty(key)){
vals.push({key:key, value: obj[key]})
}
}
return vals
}
function valueAsString(obj) {
if(typeof obj !== 'object') return obj;
return `${obj['value']} ${obj['units']}`
}
function getChildren(key, obj) {
if(Object.keys(obj).sort().toString() === "units,value"){
return {key: key, value: valueAsString(obj)}
} else {
return {key: key, children: getKeyValueAsChildren(obj) }
}
}
function getValues(properties, values = []) {
for(let key in properties) {
if(properties.hasOwnProperty(key)) {
let value = properties[key]
if(typeof value !== 'object') {
values.push({key: key, value: value})
} else if(Array.isArray(value)){
let children = []
value.map(v => {
children.push(getChildren(key, v))
})
values.push({key: `${key}List`, children: children})
}
else if(value.constructor.name === 'Object' && isNested(value)){
// I THINK THE MAIN PROBLEM IS HERE
let keys = Object.keys(value)
let children = [];
keys.forEach(key => {
children.push({key: key, children: getValues(value[key])})
})
values.push({key: key, children: children})
}
else {
values.push(getChildren(key, value))
}
}
}
return values
}
getValues(hostProperties)
this returns
[
{
"key": "clusterName",
"value": "ml6.engrlab.com-cluster"
},
{
"key": "statusProperties",
"children": [
{
"key": "loadProperties",
"children": [
{
"key": "loadDetail",
"children": [
{
"key": "restoreWriteLoad",
"children": [
{
"key": "value",
"value": 0
},
{
"key": "units",
"value": "sec/sec"
}
]
}
]
},
{
"key": "totalLoad",
"value": "0.0825921967625618 sec/sec"
}
]
},
{
"key": "secure",
"children": [
{
"key": "value",
"value": false
},
{
"key": "units",
"value": "bool"
}
]
},
{
"key": "statusDetail",
"children": [
{
"key": "licenseKeyOptionList",
"children": [
{
"key": "licenseKeyOption",
"value": "conversion enum"
},
{
"key": "licenseKeyOption",
"value": "failover enum"
}
]
},
{
"key": "connectPort",
"value": 7999
},
]
},
{
"key": "rateProperties",
"children": [
{
"key": "rateDetail",
"children": [
{
"key": "largeReadRate",
"children": [
{
"key": "value",
"value": 0
},
{
"key": "units",
"value": "MB/sec"
}
]
}
]
},
{
"key": "totalRate",
"value": "67.2446365356445 MB/sec"
}
]
},
{
"key": "online",
"children": [
{
"key": "value",
"value": true
},
{
"key": "units",
"value": "bool"
}
]
},
{
"key": "cacheProperties",
"children": [
{
"key": "cacheDetail",
"children": [
{
"key": "tripleCachePartitions",
"children": [
{
"key": "tripleCachePartitionList",
"children": [
{
"key": "tripleCachePartition",
"children": [
{
"key": "partitionSize",
"value": 768
},
{
"key": "partitionBusy",
"value": 0
},
{
"key": "partitionUsed",
"value": 0
},
{
"key": "partitionFree",
"value": 100
}
]
}
]
}
]
}
]
}
]
}
]
}
]
but I need this
[
{
"key": "clusterName",
"value": "ml6.engrlab.com-cluster"
},
{
"key": "statusProperties",
"children": [
{
"key": "loadProperties",
"children": [
{
"key": "loadDetail",
"children": [
{
"key": "restoreWriteLoad",
"value": "0 sec/sec"
}
]
},
{
"key": "totalLoad",
"value": "0.0825921967625618 sec/sec"
}
]
},
{
"key": "secure",
"value": "false bool"
},
{
"key": "statusDetail",
"children": [
{
"key": "licenseKeyOptionList",
"children": [
{
"key": "licenseKeyOption",
"value": "conversion enum"
},
{
"key": "licenseKeyOption",
"value": "failover enum"
}
]
},
{
"key": "connectPort",
"value": 7999
}
]
},
{
"key": "rateProperties",
"children": [
{
"key": "rateDetail",
"children": [
{
"key": "largeReadRate",
"value": "0 MB/sec"
}
]
},
{
"key": "totalRate",
"value": "67.2446365356445 MB/sec"
}
]
},
{
"key": "online",
"value": "true bool"
},
{
"key": "cacheProperties",
"children": [
{
"key": "cacheDetail",
"children": [
{
"key": "tripleCachePartitions",
"children": [
{
"key": "tripleCachePartitionList",
"children": [
{
"key": "tripleCachePartition",
"children": [
{
"key": "partitionSize",
"value": 768
},
{
"key": "partitionBusy",
"value": 0
},
{
"key": "partitionUsed",
"value": 0
},
{
"key": "partitionFree",
"value": 100
}
]
}
]
}
]
}
]
}
]
}
]
}
]
You might have to run more tests, as what you require seems quite arbitrary, but I believe this function does what you are looking for. It works in a similar way to yours, by simply recursing the tree, and checking for object types, and if the special case is matched.
function toKeyValue(obj) {
return Object.keys(obj).map(k => {
var value = obj[k]
var key = k
var valueName = 'children'
if(Array.isArray(value)){
key = k + 'List'
value = value.map(toKeyValue)
}else if(value !== null && typeof value === 'object'){
// check for special case
if(Object.keys(value).sort().toString() === "units,value"){
value = value.value + ' ' + value.units
valueName = 'value'
}else{
value = toKeyValue(value)
}
}else{
valueName = 'value'
}
return {
key: key,
[valueName]: value
}
})
}
Fiddle here

JSON object TypeError: Cannot set property '0' of undefined

I have two JSON objects one that holds the Buildings and the other that holds the rooms. One fails and one succeeds. They both come in code,value pairs.
Both are attached to drop down menus. The Bldgs shows the result while the rooms fails with the above error.
The bldgs JSON retrieved from the server looks like this
[{
"code": "Bldgs",
"value": "A"
}, {
"code": "Bldgs",
"value": "J"
}, {
"code": "Bldgs",
"value": "I"
}, {
"code": "Bldgs",
"value": "H"
}, {
"code": "Bldgs",
"value": "G"
}, {
"code": "Bldgs",
"value": "F"
}, {
"code": "Bldgs",
"value": "E"
}, {
"code": "Bldgs",
"value": "D"
}, {
"code": "Bldgs",
"value": "C"
}, {
"code": "Bldgs",
"value": "B"
}, {
"code": "Bldgs",
"value": "K"
}]
Where as the Rooms look like this
[{
"code": "Rooms",
"value": "1"
}, {
"code": "Rooms",
"value": "7"
}, {
"code": "Rooms",
"value": "6"
}, {
"code": "Rooms",
"value": "4"
}, {
"code": "Rooms",
"value": "3"
}, {
"code": "Rooms",
"value": "2"
}, {
"code": "Rooms",
"value": "16"
}, {
"code": "Rooms",
"value": "15"
}, {
"code": "Rooms",
"value": "14"
}, {
"code": "Rooms",
"value": "13"
}, {
"code": "Rooms",
"value": "12"
}, {
"code": "Rooms",
"value": "11"
}, {
"code": "Rooms",
"value": "9"
}]
I tried
var roomList,bldgList= [];
dropdowns.listdrops({'code':'Rooms'})
.$promise
.then(
function(data) {
$log.info("Rooms:" + data.length);
if (typeof data != "undefined") {
for(var i = 0, len = data.length; i < len; i++) {
roomList[i] = data[i].value; //ERROR HERE
};
}
}
);
dropdowns.listdrops({'code':'Bldgs'})
.$promise
.then(
function(data) {
$log.info("Blgds:" + data.length);
if (typeof data != "undefined") {
for(var i = 0, len = data.length; i < len; i++) {
bldgList[i] = data[i].value; //NO ERROR
};
} else {
$log.info('ERROR: no Drops');
}
}, function(error) {
$log.info('No Drop downs- Server error');
}
);
I even tried bypassing the server service call and doing this
var test = [{"code":"Rooms","value":"1"},ode":"Rooms","value":"7"},{"code":"Rooms","value":"6"},{"code":"Rooms","value":"4"},{"code":"Rooms","value":"3"},{"code":"Rooms","value":"2"},{"code":"Rooms","value":"16"},{"code":"Rooms","value":"15"},{"code":"Rooms","value":"14"},{"code":"Rooms","value":"13"},{"code":"Rooms","value":"12"},{"code":"Rooms","value":"11"},{"code":"Rooms","value":"9"}];`
for(var i = 0, len = test.length; i < len; i++) {
roomList[i] = test[i].value; //ERROR
};
You need to initialise roomList. var roomList,bldgList= []; should be
var roomList = [],
bldgList = [];

Categories

Resources