I need to know the best way to get following results
courseFrequency : [
{
'courses': [
'a.i'
],
'count' : 1
},
{
'courses': [
'robotics'
],
'count' : 2
},
{
'courses': [
'software engineering', 'a.i'
],
'count' : 2
},
{
'courses': [
'software engineering', 'a.i','robotics'
],
'count' : 1
}
]
from following json data.
arr = [
{
'courses': [
'a.i'
]
},
{
'courses': [
'robotics'
]
},
{
'courses': [
'software engineering', 'a.i'
]
},
{
'courses': [
'robotics'
]
},
{
'courses': [
'software engineering', 'a.i'
],
'courses': [
'software engineering', 'a.i','robotics'
]
}];
Basically i need to find out the unique courses and their frequency. What is the most optimal way to do that ?
const hash = {}, result = [];
for(const {courses} of arr){
const k = courses.join("$");
if(hash[k]){
hash[k].count++;
} else {
result.push(hash[k] = { courses, count : 1 });
}
}
Simply use a hashmap to find duplicates. As arrays are compared by reference, we need to join it to a string for referencing ( note that this will fail if a coursename contains the joining symbol ($))
There both of them are best for area relates to them.These concepts are heaving their own property and methods to accomplish a certain task like JSON used for data transfer and cross browsing aspect as the common type data value.Arrays are really good at storing ordered lists and ordering things while the cost of removing/splicing elements is a bit higher.
JSON is a representation of the data structure, it's not an object or an array.
JSON can be used to send data from the server to the browser, for example, because it is easy for JavaScript to parse into a normal JavaScript data structure.for doing an action on JSON data you need to convert it into an object which is also seamed some property like ARRAY.
Arrays are really good at storing ordered lists and ordering things while the cost of removing/splicing elements is a bit higher.
Relative link
Relative link
Related
This question already has answers here:
Group by array and add field and sub array in main array
(8 answers)
Closed 1 year ago.
As a newbie, I'm looking for the best approach to achieve the below:
Here is the Array I get from my DB query that contains a left join on the "class" table
[
{"legnumber":1,
"classcode" : "J"},
{"legnumber":1,
"classcode" : "Y"},
{"legnumber":2,
"classcode" : "J"}
]
And I would like to get something like this:
{
"legs": [
{
"legnumber" : 1,
"classes" : [
{"classcode" : "J"},
{"classcode" : "Y"}
]
},
{
"legnumber" : 2,
"classes" : [
{"classcode" : "J"}
]
}
]
}
Thanks a lot for your suggestions.
I'm using Sequelize in this project but I'm writing raw queries as I find it more convenient for my DB model.
Regards,
Nico
Hassan's answer is the more concise way to handle this, but here is a more verbose option to help understand what's happening:
const queryResults = [
{ legnumber: 1, classcode: 'J' },
{ legnumber: 1, classcode: 'Y' },
{ legnumber: 2, classcode: 'J' },
]
// create an object to store the transformed results
const transformedResults = {
legs: [],
}
// loop through each item in the queryResult array
for (const result of queryResults) {
// try to find an existing leg tha matches the current leg number
let leg = transformedResults.legs.find((leg) => leg.legnumber === result.legnumber)
// if it doesn't exist then create it and add it to the transformed results
if (!leg) {
leg = {
legnumber: result.legnumber,
classes: [],
}
transformedResults.legs.push(leg)
}
// push the classcode
leg.classes.push({ classcode: result.classcode })
}
console.log(transformedResults)
You can group your array items based on legnumber using array#reduce and then get all the values to create your result using Object.values().
const arr = [ {"legnumber":1, "classcode" : "J"}, {"legnumber":1, "classcode" : "Y"}, {"legnumber":2, "classcode" : "J"} ],
output = arr.reduce((r, {legnumber, classcode}) => {
r[legnumber] ??= {legnumber, classes: []};
r[legnumber].classes.push({classcode});
return r;
},{}),
result = {legs: Object.values(output)};
console.log(result);
I have a json string that is in the format:
[
{
clientIDs:
"WELL #6",
analyteIDs:
[
"7440-62-2",
"7440-28-0"
]
}
]
I need to convert this to:
[
{
header:
"WELL #6",
items:
[
header: "7440-62-2",
header: "7440-28-0"
]
}
]
The values without a key name are throwing me off.
Unfortunately js cannot store a key value arrays, instead you have to use an object storing key and value. So the closes result you can achieve is following:
[
{
header:
"WELL #6",
items:
[
{ header: "7440-62-2" },
{ header: "7440-28-0" }
]
}
]
For that your steps will be following:
Assuming you have an array of objects.
Assuming the keys you want to change are static and will always exist in the objects
const myObjects = [
{
clientIDs:
"WELL #6",
analyteIDs:
[
"7440-62-2",
"7440-28-0"
]
}
]
myObjects.map((myObj) => {
myObj['header'] = myObj.clientIDs;
myObj['items'] = myObj.analyteIDs.map((item) => {
return { header: item }
});
// Keep in mind, if keys are dynamic and does not exist in some objects then this will fail
delete myObj['clientIDs'];
delete myObj['analyteIDs'];
});
console.log(myObjects);
I'm getting an array from the backend that has an abritrary number of nested arrays. Each array element is a company and may or may not have a Children property which is again an array of companies that each may or may not have child companies. For example:
[
{
Name:"Company X",
Children:[
{
Name:"Company XY"
},
{
Name:"Company XZ",
Children:[
{
Name: "Company XZY" // third level of nested arrays, can be an abritrary number of levels
}
]
}
]
},
{
Name:"Company Y",
Children:[
{
Name:"Company YZ"
}
]
}
]
I have to add a "Label" property to each company object. The property is equal to the "Name" property.
How can I do this in JavaScript?
Gotta use recursion here.
function addLabelRecursive(company) {
if (company.Name) {
company.Label = company.Name;
}
if (company.Children) {
company.Children.forEach(addLabelRecursive);
}
}
This function adds a label and if children exist runs itself for each child.
Working code for your sample data
I have a fairly complex array generated from Google's natural language API. I feed it a paragraph of text and out comes lots of language information regarding such paragraph.
My end goal is to find "key words" from this paragraph, so, to achieve this I want to put all the "entities" into a flat array, count the duplicates, and then consider words with the highest amount of duplicates to be "key words". If it doesn't find any then I'll cherry pick words from entities I consider most significant.
I already know the entities that could exist:
var entities = [
'art',
'events',
'goods',
'organizations',
'other',
'people',
'places',
'unknown'
];
Here is an example structure of the array I'm working with.
input = [
{
language: {
entities: {
people: [
{
name: "Paul",
type: "Person",
},
{
name: "Paul",
type: "Person",
},
],
goods: [
{
name: "car",
type: "Consumer_good",
}
], //etc
}
}
}
];
output = ["Paul", "Paul", "car"...];
My question is - what is the best way to convert my initial array into a flat array to then find the duplicates without using a whole bunch of FOR loops?
There is no way around loops or array functions if you work with dynamic input data.
You can access all the values using this format:
input[0]["language"]["entities"]["people"][0].name
input = [
{
language: {
entities: {
people: [
{
name: "Paul",
type: "Person",
},
{
name: "Paul",
type: "Person",
},
],
goods: [
{
name: "car",
type: "Consumer_good",
}
], //etc
}
}
}
];
console.log(input[0]["language"]["entities"]["people"][0].name);
Then you could do something like this:
for (var entry in input[0]["language"]["entities"]) {
console.log(entry);
}
OR, if I understood you wrong,
You can use this to turn the javascript Object into an array using this (requires jquery):
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
var array = $.map(myObj, function(value, index) {
return [value];
});
console.log(array[0][0]);
console.log(array[0]);
console.log(array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This will output
1
[1, 2, 3]
[[1,2,3],[4,5,6]]
You could iterate through input.language.entities in a recursive way and collect all the .name properties into an array. Then you have only one for loop :-).
After doing that, you can iterate through it to find the duplicates. If you sort it alphabetical before it is easier (if two or more consecutive entries are equal, there are duplicates).
But it could be a bit dangerous if google changes the api or if it delivers crap data because of a malfunction.
Isn't input.language.entities already flat enough to work with it?
I ended up doing something like this. It's not pretty but it gets the job done.
var result = [];
var known_entities = ['art','events','goods','organizations','other','people','places','unknown'];
for(i=0; i < known_entities.length; i++){
var entity = known_entities[i];
if(language.entities[entity]){
for(var j in language.entities[entity]){
var word = language.entities[entity][j].name
result.key_words.push(word);
}
}
}
I have a collection that looks like the ff:
{
"word":"approve",
"related" : [
{
"relationshipType" : "cross-reference",
"words" : [
"note"
]
},
{
"relationshipType" : "synonym",
"words" : [
"demonstrate",
"ratify",
]
}
],
},
{
"word": "note",
"related" : [
{
"relationshipType" : "synonym",
"words" : [
"butt",
"need",
],
},
{
"relationshipType" : "hypernym",
"words" : [
"air",
"tone",
]
},
{
"relationshipType" : "cross-reference",
"words" : [
"sign",
"letter",
"distinction",
"notice",
]
},
],
}
I want to group/categorize all the objects which have a word in another object, be it
the name (as the cross-reference field of 'approve', has note. searches for the word 'note'.
or
the word is in another object's related words. like having a synonym of 'ratify' under 'approve' then looking for other objects that have have 'ratify' in any field of their related words.
Then save these to a new collection called categories.
result should Be:
{
"category": 1,
"words":["approve","note"],
}
...and the value of the word field for all the linked objects in the words array.
Any way how to do this.. i'm thinking about some sort of recursion in checking links but i'm not sure how to implement. another potential problem is going back to the parent layer creating an infinite loop of sorts.
and is it possible through map reduce?
EDIT: clarity.