find property inside nested array javascript - javascript

I have an object that contains data to display information pulled from the Notion API. I can see the data but not sure how I can extract nested array inside the current array. My goal is to use the category property to create a filter but first I need to get the string to create the condition.
Here is what the data looks like currently. How would I go about to filter out name: "commissions":
resultsArray:
0:
properties
category:
id: "sdasd"
multi_select:
0:
id:"324234"
name: "commissions"
I have tried use find but it doesn't do what I expect. My suspicion is that I will have to loop over the nested array again.

You can use find inside find condition
like this :
data.resultsArray.find(item=>item.category.multi_select.find(select=> select.name === "commissions"))
const data = {
resultsArray: [
{
category: {
id: 'sdasd',
multi_select: [
{
id: '324234',
name: 'commissions',
},
],
},
},
],
};
const result = data.resultsArray.find(item=>item.category.multi_select.find(select=> select.name === "commissions"))
console.log(result)

Related

Concentate values in a Nested Array of Object with children in JavaScript

I have a nested array of objects having path as one of the keys. The structure of the nested array is as under:
const data = [
{
Name: "item1",
path: "path1",
children:[
{
Name: "item1.1",
path: "path1.1"
},
{
Name: "item1.2",
path: "path1.2",
children:[
{
Name: "item1.2.1",
path: "path1.2.1",
children:[
{
Name: "item1.2.1.1",
path: "path1.2.1.1"
}
]
},
]
}
]
}
]
I need to concentate the path values without changing the structure of array. The expected result would be:
const newdata: [
{
Name: "item1",
path: "path1",
children:[
{
Name: "item1.1",
path: "path1/path1.1"
},
{
Name: "item1.2",
path: "path1/path1.2",
children:[
{
Name: "item1.2.1",
path: "path1/path1.2/path1.2.1",
children:[
{
Name: "item1.2.1.1",
path: "path1/path1.2/path1.2.1/path1.2.1.1",
}
]
}
]
}
]
}
]
How to do it in JavaScript?
This would be best done with a recursive Function, that iterates through your entire data structure and sets the Path by building it up while traversing your data structure.
The first version creates the path information from scratch, by using the index of each child in the array and building up the index that gets appended to the path string.
Further below i've provided changes to this version, that uses the already existing path information and concatenates the path string as you asked for.
// Recursive Function to iterate through a possible endless nested data structure
// We provide the parameter for the previous index and parentPath to build up the path string
function recursivePath(data, index = "", parentPath = "") {
// We will get an Array with all Items as 'data' which we will loop with forEach
data.forEach((item, i) => {
// We recreate the the index of the item by adding current index of
// this item in the data array to the index structure of the parent items
let itemIndex = index !== "" ? `${index}.${i+1}` : `${i+1}`;
// We do the same for the path, we take the path of the parent
// and add the path information of this item to it.
let itemPath = `${parentPath}path${itemIndex}`;
// We set the path property of this item, which will be returned
// after all items of this data are done.
item.path = itemPath;
// We check if this item has some nested childrens and if it does,
// we will repeat this process for all those childrens
if (item.children && typeof item.children.length) {
// We provide the newly created index on which those childs will build upon
// as the same with the path.
// This can be a bit confusing, but we assume here, that the function will return
//the finished childrens and we save the result to our childrens property.
item.children = recursivePath(item.children, itemIndex, itemPath + "/");
}
});
// Lastly we iterated through all Items and are sure to set the Path for all Items
// and their childrens nested inside and return the entire data array.
return data;
}
// Your Data
const data = [{
Name: "item1",
path: "path1",
children: [{
Name: "item1.1",
path: "path1.1"
},
{
Name: "item1.2",
path: "path1.2",
children: [{
Name: "item1.2.1",
path: "path1.2.1",
children: [{
Name: "item1.2.1.1",
path: "path1.2.1.1"
}]
}, ]
}
]
}];
// We use the recursive function and output the results to the console
console.log(recursivePath(data));
If you would use the stored Path value of each item, you could just append the Value onto the parentPath String and save this new String into item.path
You would just change the line in the function, that creates the itemPath a little bit and you can remove the line that creates the itemIndex.
The parameter itemIndex of the recursive function isn't needed anymore and can be removed too.
// We wont need the index anymore, as we use the already existing
// Path value for the Index of each item
function recursivePath(data, parentPath = "") {
// We create a temporary new Data variable, to hold our changed elements.
let newData = [];
data.forEach((item, i) => {
// We'll create a copy of an Object to modify
let copyItem = {};
// Object.assign() copies all enumerable properties of one object to another
// We'll then use the new object to modify all properties,
// thous the original item will be untouched.
Object.assign(copyItem, item)
// We append the path information of this items path value
// onto the parentPath string
let itemPath = `${parentPath}${item.path}`;
// Same as before
copyItem.path = itemPath;
// Same as before
if (copyItem.children && typeof copyItem.children.length) {
// We removed the itemIndex, as it isnt needed anymore
copyItem.children = recursivePath([...copyItem.children], itemPath + "/");
}
// After modification we add the object to the temporary array
// and return it after all items are modified.
newData.push(copyItem);
});
// Returning the newly created array
return newData;
}
// Your Data
const data = [{
Name: "item1",
path: "path1",
children: [{
Name: "item1.1",
path: "path1.1"
},
{
Name: "item1.2",
path: "path1.2",
children: [{
Name: "item1.2.1",
path: "path1.2.1",
children: [{
Name: "item1.2.1.1",
path: "path1.2.1.1"
}]
}, ]
}
]
}];
// We use the recursive function and output the results to the console
console.log(recursivePath(data));
console.log(data);
Fur further clarification of why we need to copy Arrays and/or Objects provided as a parameter:
Arrays and Objects arent provided as their full content, as those could be huge data structures and moving and copying those every time they are provided as parameter would cause a huge memory dump as every parameter would be a redundant content of their original data.
Therefore only references or in other languages called pointers are provided, which point or reference the memory location, where the content is stored.
If you provide an array or object for a function and modify them, the modification will be stored via the reference on the original array and therefore all further access to this variable will also have those modification.
Thats why we need to copy the content of those variables into new array or objects and return those as they are themself new references but to another array with the same but slightly modified content.
The redundancy doesn't matter, as those variables are only block/closure scoped with the prefix of let before, therefore they are garbage collected after the function resolved.

Using .map to loop array of objects and store new array in object value

I'm currently getting data from a database of an array of objects. I need these objects to be reformatted to work with a UI package that we're using that requires these objects to look a specific way. The main array should look like this:
[{
trim: 123,
id: 123,
children: [{
trim: 123,
id: 123,
}],
}]
I'm successfully looping through the main array data and reformatting it into a new array using .map; however, I'm having issues doing the same thing but for the children key that's found in each object of the main array. Wondering if anyone could help me figure out the proper way to do this. I'll add my current code below and will be able to clarify more if needed.
if (this.$store.state.models.models) { // this is checking for the main array coming from the database
const reformattedModels = this.$store.state.models.models.map((model) => {
const tableModel = {
trim: model.name,
id: model.id,
children: // Need to loop here to reformat array of objects that goes for the children key,
};
return tableModel;
});
return reformattedModels;
}
The array that I need to loop through for the children key is one of the keys found in the main array from the backend. It's called "trims" and looks like this:
[{
name: 123,
id: 123,
}]
Create a reference to the function and call it recursively:
if (this.$store.state.models.models) {
// store the function
const mapper = model => ({
trim: model.name,
id: model.id,
// use it for children, if there are any
children: model.children?.map(mapper)
});
// use it for the models
return this.$store.state.models.models.map(mapper);
}
I'm using optional chaining (?.) to call .map() only if model.children != undefined

Object spread inside of new array

I have a Node.js program that is using Mongo Atlas search indexes and is utilizing the Aggregate function inside of the MongoDB driver. In order to search, the user would pass the search queries inside of the query parameters of the URL. That being said, I am trying to build a search object based on if a query parameter exists or not. In order to build the search object I am currently using object spread syntax and parameter short-circuiting, like so:
const mustObj = {
...(query.term && {
text: {
query: query.term,
path: ['name', 'description', 'specs'],
fuzzy: {
maxEdits: 2.0,
},
},
})
}
This is a shortened version, as there are many more parameters, but you get the jest.
In a MongoDB search query, if you have multiple parameters that must meet a certain criteria, they have to be included inside of an array called must, like so:
{
$search: {
compound: {
must: [],
},
},
}
So, in order to include my search params I must first turn my mustObj into an array of objects using Object.keys and mapping them to an array, then assigning the searches 'must' array to the array I've created, like so:
const mustArr = Object.keys(mustObj).map((key) => {
return { [key === 'text2' ? 'text' : key]: mustObj[key] };
});
searchObj[0].$search.compound.must = mustArr;
What I would like to do is, instead of creating the mustObj and then looping over the entire thing to create an array, is to just create the array using the spread syntax and short-curcuiting method I used when creating the object.
I've tried the below code, but to no avail. I get the 'object is not iterable' error:
const mustArr = [
...(query.term && {
text: {
query: query.term,
path: ['name', 'description', 'specs'],
fuzzy: {
maxEdits: 2.0,
},
},
})
]
In all, my question is, is what I'm asking even possible? And if so, how?
Corrected based on #VLAZ comment:
while spread with array [...(item)], item has to be array (iterable).
When you use short-circuit, the item as below,
true && [] ==> will be `[]` ==> it will work
false && [] ==> will be `false` ==> wont work (because false is not array)
try some thing like (Similar to #Chau's suggestion)
const mustArr = [
...(query.term ? [{
text: {
query: query.term,
path: ['name', 'description', 'specs'],
fuzzy: {
maxEdits: 2.0,
},
},
}] : [])
]

Matching value of data object in VueJs

How can I retrieve the data from a data object in Vue?
I have data in this format:
datasets: [{
text:"Cars",
value: "[1,2,3]"
},
{
text:"Trains",
value: "[1,4,10]
}
]
Now I from route props I get the following info:
this.selectedText= this.$route.name;
Where this.$route.name is "Cars" for example.
Now I want to take this use this.selectedValue to get corresponding Value from this array:
so if this.selectedText="Cars" then this.selectedValue=[1,2,3] or based on this I want to retrieve the value of given text.
Create a method and use this code to find out the matching one.
function setSelectedValue() {
let matchingDatSet = this.datasets.find(ele => ele.text == this.selectedText);
if(matchingDataSet !== undefined) {
this.selectedValue = matchingDataSet.value;
}
}

How to get a list of Objects instead of a list of Maps in gremlin-javascript

Hi I am now using gremlin -javascript to do some queries in AWS neptune DB.
I have a query like
[errRelatedTicket, relatedTicket] = await to(g.V().hasId(a).in_('r').valueMap(true).toList());
then I get a list of map like:
[
Map {
id: 1
},
Map {
id: 2
},
]
But can I use gremlin query to get id and properties in key/value pairs directly instead?
what I expect is:
[
{ id: 1 },
{ id: 2 },
]
I don't know "gremlin-javascript", you can research more in the document. But I know there's a simple way to do the conversion in plain javascript, use .map and Object.fromEntries. Hope you'll find a better way.
var listMap = [
new Map([[ 'id', 1 ]]),
new Map([[ 'id', 2 ]]),
];
var listObject = listMap.map(m => Object.fromEntries(m));
console.log(listObject);
If you always want to return objects rather than maps, you can set this configuration in your DriverRemoteConnection construct, like so: const dc = new DriverRemoteConnection(CLUSTER_URL, { mimeType: 'application/vnd.gremlin-v2.0+json' });

Categories