Get Object's Parent Without Using Loops in Lodash - javascript

Is there a way/function(s) in lodash to get the object's parent of a particular pet id without having to write code that would loop over each person/pet?
For example: _.getParent(people, pets.id => 11) // returns {"type":"Fish", "id":11}.
let people = [
{
"name": "Jack",
"pets": [
{ "type":"Frog", "id":23 },
{ "type":"Bird", "id":57 },
{ "type":"Fish", "id":11 }
]
},
{
"name": "Dawn",
"pets": [
{ "type":"Lion", "id":89 },
{ "type":"Duck", "id":51 }
]
},
{
"name": "Anne"
},
{
"name": "Josh",
"pets": []
}
]

For example,
_.filter(
_.flatMap(people, 'pets'),
t => t && t.id === 11
)

Related

How to filtering out the multiple nested object in Javascript object

Javascript
I have a nested array of objects, I'm trying to filter the given array of objects using a property from the third level of its array property value. For example, from the below array I like to filter the entire array using the property ListId: 10
Example
let test = {
"test":true,
"group":[
{
"name":"header",
"value":[
{
"id":"0",
"list":[
{
"ListId":10,
"name":"string1",
"state":"BY",
"techId":0
},
{
"ListId":11,
"name":"string2",
"state":"BY"
},
{
"ListId":12,
"name":"string3",
"state":"BY"
}
]
}
]
},
{
"name":"header2",
"value":[
{
"id":"01",
"list":[
{
"ListId":100,
"name":"string1",
"state":"BY",
"techId":0
},
{
"ListId":111,
"name":"string2",
"state":"BY"
},
{
"ListId":121,
"name":"string3",
"state":"BY"
}
]
}
]
}
]
}
Filtervalue with ListId = 10
Expected output :
{
"test":true,
"group":[
{
"name":"header",
"value":[
{
"id":"0",
"list":[
{
"ListId":10,
"name":"string1",
"state":"BY",
"techId":0
}
]
}
]
}
]
}
How can I use the filter method using javascript to get this expected result?
You can two it in two times :
First, filter the list arrays,
Secondly filter the groups array using the some method
let test= {
"test": true,
"group": [
{
"name": "header",
"value": [
{
"id": "0",
"list": [
{
"ListId": 10,
"name": "string1",
"state": "BY",
"techId": 0
},
{
"ListId": 11,
"name": "string2",
"state": "BY"
},
{
"ListId": 12,
"name": "string3",
"state": "BY"
}
]
}
]
},
{
"name": "header2",
"value": [
{
"id": "01",
"list": [
{
"ListId": 100,
"name": "string1",
"state": "BY",
"techId": 0
},
{
"ListId": 111,
"name": "string2",
"state": "BY"
},
{
"ListId": 121,
"name": "string3",
"state": "BY"
}
]
}
]
}
]
}
test.group.forEach(group => {
group.value.forEach(value => {
value.list = value.list.filter(list => list.ListId === 10)
})
})
test.group = test.group.filter(group => group.value.some(value => value.list.length > 0))
console.log(test)
Note : You should use plural names for you arrays, it helps understanding the data. For example lists not list for the array.
let z ={"group1": [
{
"name": "header",
"value": [
{
"id": 0,
"list": [
{
"ListId": 10,
"Name": "string1"
},
{
"ListId": 11,
"Name": "string2"
}
]
}
]
}
]}
// This function was written from understading that 'group1' is not a fixed property, but part of a dynamic list due to the number '1'
const getItemByListId = (list, listId) => {
const listKeys = Object.keys(list);
const selectedListKey = listKeys.find(key => {
const groupItems = list[key];
const selectedItem = groupItems.find(({ value: nestedItems }) => {
const selectedNestedItem = nestedItems.find(({ list }) => {
const selectedList = list.find(({ ListId }) => ListId === listId)
return selectedList;
});
return selectedNestedItem;
});
return selectedItem;
});
if (!selectedListKey) {
return null;
}
return list[selectedListKey];
};
console.log(getItemByListId(z, 10));

How can i change the organization of my json?

Hey i tried to transform a json file (as a js object but I can not do it). Here is an example of my problem:
Input object
{
"peoples": [
{
"name": "Alain",
"nationality": "Italian"
},
{
"name": "John",
"nationality": "French"
},
{
"name": "FOO",
"nationality": "French"
}
]
}
Output object
{
"nationality": {
"french": {
"peoples": [{ "name": "John" }, { "name": "FOO" }]
},
"italian": {
"peoples": [{ "name": "Alain" }]
}
}
}
How can i do this ? maybe Lodash but i have not find any way to do this. Can anyone help me ?
You can use a simple reduce:
const obj = {
"peoples": [{
"name": "Alain",
"nationality": "Italian"
},
{
"name": "John",
"nationality": "French"
},
{
"name": "FOO",
"nationality": "French"
}
]
}
const output = obj.peoples.reduce((a, {nationality: n, ...rest}) => {
const x = a.nationality[n]
if (x) x.push(rest)
else a.nationality[n] = [rest]
return a
}, { nationality: {} })
console.log(output)
Note, I've used a spread operator to get the rest of the properties, so if you were to add more properties to each person, then those would be included in the new object.

How to find the value nested inside an array of objects

Here I have to get value of file_info, I tried doing it using array.includes and array.find(), but got undefined.
My confusion here is related to, under 'facts', the first value is "==", then it has array of values associated to it. I could not figure out to find the values inside that nested object.
I even tried array.find(facts).contains(fileinfo) that did not work as well.
How can I solve this ??
"data": [
{
"task-id": "126e7267",
"type": "A",
"output": {...}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
},
....
]
}
},
{
"task-id": "5f557eac",
"type": "C",
....
},
],
I have tried to validate your json string. It seems to be invalid. For answering this question , i would assume below string to be your json :
{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}
I had tried to figure out a repetative pattern in your json but since "#value" tag is seen inside only one "facts" object below code should help you getting started . For given json , below code prints the value of "file_info"(Here , i'am assuming that "file_info" should be followed by a colon(:) i.e. "a0s5b2e6e739" is the value you are looking for) :
var jsonStr = '{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}';
var jsonObj = JSON.parse(jsonStr);
//If there is a repetative pattern , you can replace this hard coding with your pattern.
var objArray = jsonObj["data"][1]["output"]["facts"][0]["=="][1]["#value"]["facts"];
console.log(objArray);
if(objArray && objArray.length >0){
for(let i =0;i<objArray.length;i++){
if(objArray[i] && objArray[i]["=="] && objArray[i]["=="].length > 0 && objArray[i]["=="][0]["file_info"]){
//here "file_info" is fetched
console.log('here ',objArray[i]["=="][0]["file_info"]);
}
}
}
Hope above code helps you to get started.
You can map and filter the object/array to get the result if the format is fixed. Here, I am writing to a Map and retrieving the property I need at the very end.
let data = [
{
"task-id": "126e7267",
"type": "A",
"output": {}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
}
]
}
},
{
"task-id": "5f557eac",
"type": "C",
"output": {}
}
]
const map = new Map()
const facts = data
.map(d => d.output)
.filter(o => o.hasOwnProperty('facts'))
.map(d => d.facts)
.map(i => i[0]["=="][1])
.map(d => d["#value"].facts)
const item = facts.forEach(o => o.forEach(i => map.set(i["=="][0], i["=="][1])))
console.log(map.get("file_info"))

javascript map object multidimension

i have this data structure:
tree = [
{
"name": "Men Section",
"categories": [
{
"name": "Clothings",
"Subcategories": [
{
"name": "Jackets",
"products": [
{
"name": "jacket 01",
"price": 100
},
{
"name": "jacket 02",
"price": 140
},
// ..and so on
]
]
},
// ..and so on
]
} // ..and so on
]
how can i add new property in products item isSelected: false in javascript (ES5 or ES6 is fine) so the object will be
{
"name": "jacket 01",
"price": 100,
"isSelected": false
}
?
It could be useful, it works for me
tree.forEach(base => {
base.categories.forEach(categories => {
categories.Subcategories.forEach(subCategory =>{
subCategory.products.forEach(product => product.isSelected = false)
})
});
});
so yeah, i should traverse deep to the object with nested foreach. i came up with this:
tree.categories.forEach(function (category) {
category.subcategories.forEach(function (subcategory) {
subcategory.products.forEach(function (product) {
product.isSelected = false;
})
})
})
thanks for the enlightment

Lodash iterate nested loops

I am trying to iterate through below Collections JSON object. I am trying to find collection elements which have one of the tags from tagArray. Basically this is a filter exercise to have collection elements that have tags as selected from the tagArray.
{
1: {
"description": "AAA",
"tags": [
{
"name": "tag1",
},
{
"name": "tag2",
},
{
"name": "tag3",
},
],
"name": "XYZ",
},
2: {
"description": "BBB",
"tags": [
{
"name": "tag1",
}
],
"name": "CCC",
},
3: {
"description": "xms",
"tags": [],
"name": "Huo",
},
4: {
"description": "asd",
"tags": [],
"name": "TXS",
}
}
tagArray looks like this : [ tag1, tag2, ... ]
I have coded it as below using lodash and it works fine. But I am not sure if I can improve this further and how?
const filterByTags = (collections, filterTags) => {
let filteredCollections = _.pickBy(collections, (collection) => {
let collectionWithTag = false;
_.map(collection.tags, (collectionTag) => {
if (filterTags.indexOf(collectionTag.name) !== -1) {
collectionWithTag = true;
return collectionWithTag;
}
});
return collectionWithTag;
});
return filteredCollections;
};
You don't want to use pickBy but rather filter (Lodash/native)
You don't want to use map but rather some (Lodash/native)
You don't want to use indexOf but rather includes (Lodash/native)
function filterByTags(collections, filterTags) {
return _.filter(collections, collection => {
return _.some(collection.tags, collectionTag => {
return _.includes(filterTags, collectionTag.name);
});
});
}

Categories