How do I make deduped array from object property? - javascript

I am looking for a way to loop over an array of objects and make a new array from the contents of an object property. See the array below. I want to make an array called topics (with no duplicates) from each of the topic properties on each object.
const data = [
{
topics [
"tutorial",
"JS",
"Video"
],
...
},
{
topics [
"tutorial",
"CSS",
"Testing"
],
...
},
{
topics [
"HTML",
"JS",
"Music"
],
...
}
]
I was thinking of:
let topics = []
data.forEach((item) => {
topics.push(item.topics, ...topics)
})

You need to use flatMap method to flat the topics together, and with new Set(Array) you will get the unique values.
const data = [
{
topics: [
"tutorial",
"JS",
"Video"
],
},
{
topics: [
"tutorial",
"CSS",
"Testing"
],
},
{
topics: [
"HTML",
"JS",
"Music"
],
}
]
const topics = new Set(data.flatMap(item => item.topics))
console.log(Array.from(topics))

Related

jq : how to extract attribute value from JSON conditionally

I'm trying to extract all the IDs (id) of objects without the contentType attribute from the following JSON:
{
"version":"1.5.0",
"metadata":{
"version":"1.5.0",
"createdOn":"2023-01-01"
},
"fileId":"1",
"CanBeAnyName":[
{
"id":"BT-02",
"contentType":"file",
"readOnly":true
},
{
"id":"BT-03",
"readOnly":true
}
],
"AlsoCanBeAnyName":[
{
"id":"BT",
"contentType":"empty"
},
{
"contentType":"group",
"content":[
{
"id":"BT-Care",
"_repeatable":true,
"content":[
{
"id":"BT-90-care",
"contentType":"group",
"content":[
{
"id":"GR-300-analyze",
"contentType":"field"
},
{
"id":"BT-10"
}
]
}
]
}
]
}
]
}
The jq command I'm using at the moment is:
walk(if (type == "object" and .id) then if ((.id | startswith("BT")) and has("contentType") | not) then .id else empty end else . end)
Result:
{
"version": "1.5.0",
"metadata": {
"version": "1.5.0",
"createdOn": "2023-01-01"
},
"fileId": "1",
"CanBeAnyName": [
"BT-03"
],
"AlsoCanBeAnyName": [
{
"contentType": "group",
"content": [
"BT-Care"
]
}
]
}
Expected result:
["BT-03", "BT-Care"] or even better to iterate down in the nested object ["BT-03", "BT-Care", "BT-10"]
How can I achieve this, please?
Thanks!
You could traverse the document tree using .., filter for objects, and select by all your filters. Wrap that in array brackets to get an array.
[.. | objects | select(
(has("contentType") | not) and has("id") and (.id | startswith("BT"))
).id]
[
"BT-03",
"BT-Care",
"BT-10"
]
Use the -c flag to have the array printed in one single line: ["BT-03","BT-Care","BT-10"]

Match object by array keys - Lodash

Hello i have an array of objects that looks like:
[
{
"id": "ae588a6b-4540-5714-bfe2-a5c2a65f547b",
"name": "Peter casa",
"skills": [
"javascript",
"es6",
"nodejs"
]
},
{
"id": "ae588a6b-4540-5714-bfe2-a5c2a65f547a",
"name": "Peter Coder",
"skills": [
"javascript",
"es6",
"nodejs",
"express"
]
}
]
and i'm trying to get the best match based on skills, i'm using lodash and the idea is resolve:
passing "skills": [
"javascript",
"es6",
"nodejs",
"express"
] get "Peter Coder" instead of "Peter casa" because the first one match all the skills in the array given, is there any lodash method to perform this?
Edit:
In this particular example, the function needs to get the candidate with is a better fit, for instance, if i pass skills: "skills": [
"javascript",
"es6",
"nodejs"
] even if it is a perfect match for the first one i need to choose the second because it matches the skills and has more skills, so is a better match
With lodash you could use intersection as #Tuan Anh Tran suggested:
const users = [
{
id: 'ae588a6b-4540-5714-bfe2-a5c2a65f547b',
name: 'Peter casa',
skills: ['javascript', 'es6', 'nodejs'],
},
{
id: 'ae588a6b-4540-5714-bfe2-a5c2a65f547a',
name: 'Peter Coder',
skills: ['javascript', 'es6', 'nodejs', 'express'],
},
]
let skillsByUsers = {}
const skills = ['javascript', 'es6', 'nodejs', 'express']
users.map(user => {
const skillValue = _.intersection(user.skills, skills).length
skillsByUsersTwo = {
...skillsByUsersTwo,
[user.id]: skillValue
}
})
Without lodash:
let skillsByUsers = {}
const skills = ['javascript', 'es6', 'nodejs', 'express']
skills.map(skill => {
users.map(user => {
if (user.skills.includes(skill)) {
const userSkillValue = skillsByUsers[user.id] || 0
skillsByUsers = {
...skillsByUsers,
[user.id]: userSkillValue + 1,
}
}
})
})
they print exactly the same output:
lodash
{
'ae588a6b-4540-5714-bfe2-a5c2a65f547b': 3,
'ae588a6b-4540-5714-bfe2-a5c2a65f547a': 4
}
without lodash
{
'ae588a6b-4540-5714-bfe2-a5c2a65f547b': 3,
'ae588a6b-4540-5714-bfe2-a5c2a65f547a': 4
}
lodash has a method call intersection https://lodash.com/docs/#intersection
you can pass the array of skill and intersect it with each developer's skill. => get the length of that intersection as score and return the one with highest score.

Javascript: Help Parsing weird JSON payload

I am trying to parse the following JSON payload:
{
"results":[
[
298.648132,
280.68692,
356.54184,
388.085541,
183.491806,
-484.676086,
-468.069916,
-446.741699
],
[
299.641846,
285.005798,
358.563812,
389.283997,
212.144806,
-485.533844,
-469.071533,
-447.885406
],
[
302.24469,
291.76059,
362.658936,
392.376129,
217.732513,
-484.816711,
-468.566711,
-447.615082
],
[
303.058899,
297.929199,
365.46994,
393.894928,
213.591797,
-486.055756,
-469.872986,
-449.343323
],
[
304.604095,
304.826233,
369.112122,
396.274597,
206.882492,
-486.385498,
-470.249512,
-450.089935
],
[
305.541901,
306.31842,
370.016907,
396.985413,
200.299408,
-486.345032,
-470.176208,
-450.01059
],
[
305.137024,
306.015381,
369.381042,
396.26059,
196.422821,
-487.490143,
-471.321533,
-451.191711
],
[
306.182373,
307.574707,
370.42627,
397.127747,
206.874603,
-487.188477,
-471.038483,
-450.869781
],
[
307.108887,
309.183777,
371.413666,
397.890198,
234.509079,
-486.957367,
-470.937103,
-450.646393
],
[
308.208923,
310.277588,
372.322968,
398.777618,
244.5168,
-486.2995,
-470.352631,
-449.89325
],
[
308.676208,
310.526123,
372.360626,
398.743317,
250.976288,
-486.666687,
-470.868408,
-450.324463
],
[
308.910583,
310.629242,
372.255676,
398.59491,
252.538498,
-487.001068,
-471.305817,
-450.616699
]
],
"columns":[
"5bb6a5d20ff4c313aab7241c.value.value",
"5bb6a5d30ff4c313aab72421.value.value",
"5bb6a5d30ff4c313aab72425.value.value",
"5bb6a5d30ff4c313aab72426.value.value",
"5bb6a5d30ff4c313091fe079.value.value",
"5bb6a5d30ff4c313091fe07b.value.value",
"5bb6a5d30ff4c313091fe07c.value.value",
"5bb6a5d40ff4c313091fe07f.value.value"
]
}
I am only interested in the "results" section. I will end up plotting these values.
I am proficient in C++, but new to JavaScript.
I've found plenty of examples with typical JSON strings, but I haven't found anything that works for this yet.
Thanks for the help.
Try the JSON.parse() function:
const payload = // your json payload
const json = JSON.parse(payload);
const results = json.results;
If you can copy-paste your json to your JS code directly then try
const payload = {"results": [ ... } // your json
const results = payload.results;
const payload ={"results":[[298.648132,280.68692,356.54184,388.085541,183.491806,-484.676086,-468.069916,-446.741699],
[299.641846,285.005798,358.563812,389.283997,212.144806,-485.533844,-469.071533,-447.885406],
[302.24469,291.76059,362.658936,392.376129,217.732513,-484.816711,-468.566711,-447.615082],
[303.058899,297.929199,365.46994,393.894928,213.591797,-486.055756,-469.872986,-449.343323],
[304.604095,304.826233,369.112122,396.274597,206.882492,-486.385498,-470.249512,-450.089935],
[305.541901,306.31842,370.016907,396.985413,200.299408,-486.345032,-470.176208,-450.01059],
[305.137024,306.015381,369.381042,396.26059,196.422821,-487.490143,-471.321533,-451.191711],
[306.182373,307.574707,370.42627,397.127747,206.874603,-487.188477,-471.038483,-450.869781],
[307.108887,309.183777,371.413666,397.890198,234.509079,-486.957367,-470.937103,-450.646393],
[308.208923,310.277588,372.322968,398.777618,244.5168,-486.2995,-470.352631,-449.89325],
[308.676208,310.526123,372.360626,398.743317,250.976288,-486.666687,-470.868408,-450.324463],
[308.910583,310.629242,372.255676,398.59491,252.538498,-487.001068,-471.305817,-450.616699]],
"columns":["5bb6a5d20ff4c313aab7241c.value.value","5bb6a5d30ff4c313aab72421.value.value",
"5bb6a5d30ff4c313aab72425.value.value","5bb6a5d30ff4c313aab72426.value.value",
"5bb6a5d30ff4c313091fe079.value.value","5bb6a5d30ff4c313091fe07b.value.value",
"5bb6a5d30ff4c313091fe07c.value.value","5bb6a5d40ff4c313091fe07f.value.value"]}
const results = payload.results;
console.log(results);

Javascript/json keep in database and special chars

I have layout builder in React to keep data structure and text I use ImmutableJS objects.
Such structure with attributes as text or css styles is saved into database as JSON.
To make it JSON I using json-immutable library: serialize, deserialize functions.
After save in database I provide configuration for react components as javascript variables. For example my backend generate js file with variables or small part is printing directly in html code using script tag.
Data are JSON or decoded javascript.
The biggest problem I have with save special chars.
For example if someone set ' single quote in some attribute it is saved directly.
But when I print it in html code as
var myConfig = '{anyjson}';
when inside JSON is single quote parser throw error. The same with double quotes, & (ampersant) or any chars used in html code like <,/>
Single quote I replace to \' when I print it in html code.
But I think does exists any way to save keep all data in JSON and still they will easy to decode by deserialize function to parse JSON to ImmutableJS objects.
Code example
https://jsfiddle.net/jaroapp/2yzud6ua/2/
var structure = {
"__iterable":"Map",
"data":[
[
"entityMap",
{
"__iterable":"Map",
"data":[
[
"html_el_qb7tyhi",
{
"__iterable":"Map",
"data":[
[
"imported",
false
],
[
"path",
"html_el_qb7tyhi"
],
[
"componentData",
{
"__iterable":"Map",
"data":[
]
}
],
[
"draftjsObject",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"draftjs",
true
],
[
"data",
{
"__iterable":"OrderedMap",
"data":[
[
"text",
"B&B is the best company. It's my hope for new markets."
]
]
}
],
[
"chunk",
null
],
[
"style",
{
"__iterable":"OrderedMap",
"data":[
[
"background-image",
"url(\"/path/to/image.jpg\")"
]
]
}
],
[
"attr",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"runEditor",
false
],
[
"entityMap",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"type",
"div"
],
[
"key",
"html_el_qb7tyhi"
]
]
}
],
[
"html_el_2dgupn7",
{
"__iterable":"Map",
"data":[
[
"imported",
false
],
[
"path",
"html_el_2dgupn7"
],
[
"componentData",
{
"__iterable":"Map",
"data":[
]
}
],
[
"draftjsObject",
{
"entityMap":{
},
"blocks":[
{
"key":"3ia22",
"text":"Text saved with html inside",
"type":"unstyled",
"depth":0,
"inlineStyleRanges":[
],
"entityRanges":[
],
"data":{
}
}
]
}
],
[
"draftjs",
true
],
[
"data",
{
"__iterable":"OrderedMap",
"data":[
[
"text",
null
],
[
"html",
"<p class=\"md-block-unstyled\">Text saved with html inside</p>"
]
]
}
],
[
"chunk",
null
],
[
"style",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"attr",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"runEditor",
false
],
[
"entityMap",
{
"__iterable":"OrderedMap",
"data":[
]
}
],
[
"type",
"div"
],
[
"key",
"html_el_2dgupn7"
]
]
}
]
]
}
],
[
"containersMap",
{
"__iterable":"Map",
"data":[
]
}
],
[
"componentsMap",
{
"__iterable":"Map",
"data":[
[
"entityMap",
{
"__iterable":"OrderedMap",
"data":[
]
}
]
]
}
]
]
};
Such structure I set as parameter into ReactJS component.
If I set it as JSON and wrap in quotes then the browser throws an error. If I set it as JavaScript object into the React component I can't make ImmutableJS from this one, because this structure is read by this
https://www.npmjs.com/package/json-immutable library (I use the same to make JSON from Immutable JS to save it in database);
Thanks in advance for any hints.
I solved this problem. Short description, maybe will helpful for someone.
I get file with deserialize function form json-immutable package. And I modified function deserialize to
export function deserialize(json){
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if(typeof json==='string'){
return JSON.parse(json, function(key, value, options){
return revive(key, value, options);
});
}else{
return JSON.parse(JSON.stringify(json), function(key, value, options){
return revive(key, value, options);
});
}
}
Function in package use JSON.parse for param. Maybe it's not the most elegant solution but I don't have time to find way to don't "re-json" object. Standard Object.keys and map return origin object.

Insert object into MongoDB object's array

I'm trying to add an object into an empty array that is stored in one of my collections.
Currently this is how I have my collection setup:
[
{
"name": "user_added",
"DRGs": []
},
...
]
How can I insert an object into the collection so that it looks like this;
[
{
"name": "user_added",
"DRGs": [
{
"code": "491",
"name": "Back & neck procedures"
}
]
},
...
]
Check out $push documentation.
You should be able to accomplish your goal with the following:
var collectionName = 'users'; // or whatever your actual collection name is
var objectToPush = {
code: "491",
name: "Back & neck procedures"
};
db.collection(collectionName).updateOne(
{"name": "user_added"},
{ $push: { "DRGS": objectToPush }}
);

Categories

Resources