React Native - get value of json depending on dynamic state - javascript

I have a json getting from API and store it into this.state.data like :
[
{
"name": "Primary Category",
"value": [
{
"value": "Fracture",
"Diagnosis_Code": ["DIAG003"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 3,
"FK_Diagnosis_Category_ID": 1
},
{
"value": "Osteoarthritis",
"Diagnosis_Code": ["DIAG001"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 1,
"FK_Diagnosis_Category_ID": 1
},
{
"value": "Osteonecrosis",
"Diagnosis_Code": ["DIAG002", "DIAG004"],
"name": "Primary Category",
"FK_Diagnosis_Content_ID": 2,
"FK_Diagnosis_Category_ID": 1
},
]
},
{
"name": "Anatomy",
"value": [
{
"value": "Hip",
"Diagnosis_Code": ["DIAG001"],
"name": "Anatomy",
"FK_Diagnosis_Content_ID": 4,
"FK_Diagnosis_Category_ID": 2
},
{
"value": "Pelvis",
"Diagnosis_Code": ["DIAG002", "DIAG003", "DIAG004"],
"name": "Anatomy",
"FK_Diagnosis_Content_ID": 6,
"FK_Diagnosis_Category_ID": 2
}
]
}
]
and I have a dynamic state using a function like this:
onChangeTextPress(key, value){
this.state.selected[key] = value
//another code
}
the example of this.state.selected is
[ 'Primary Category': 'Fracture', Anatomy: 'Hip']
I want to get FK_Diagnosis_Content_ID json depending on which this.state.selected[key] and it's value filled
so depending of selected example, I will have a result: [3, 4]
because json have a key called name and the value is Primary Category, and the value of selected state Primary Category is Fracture so I have a value of FK_Diagnosis_Content_ID in json, likewise about the Anatomy: 'Hip'
I don't know if you all know what I want, but feel free to asking me if you need another information,
hope someone can help me

You can get use of Object.keys() and Array.prototype.includes().
Sample 1
// Let's assume you have the below structure
const data = { 'Primary Category': 'Fracture', Anatomy: 'Hip' }
Object.keys(data).forEach((key) => console.log(key))
// Output:
// Primary Category
// Anatomy
So to get the desired value you can use something like below
Sample 2
// this.state.selected => { 'Primary Category': 'Fracture', Anatomy: 'Hip' }
const keys = Object.keys(this.state.selected);
const result = [];
this.state.data.forEach((d) => {
if(keys.includes(d.name)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);
// Output: [3,4]
Sample 3
// this.state.selected => [{ 'Primary Category': 'Fracture'}, {Anatomy: 'Hip' }]
// Since we know there is only one key in every object
const keys = this.state.selected.map((s) => Object.keys(s)[0])
const result = [];
this.state.data.forEach((d) => {
if(keys.includes(d.name)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[keys.indexOf(d.name)][d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);
// Output: [3,4]

You can use this just as
const key = Object.keys(this.state.selected);
const response = [];
this.state.data.forEach((d) => {
if(key.includes(d.tag)) {
d.value.forEach((v) => {
if(v.value === this.state.selected[d.name]) {
result.push(v['FK_Diagnosis_Content_ID']);
}
})
}
});
console.log(result);

Related

nested filter array javascript

I want to create a nested filter in js
when I filter my array primary data is affected and changed but I need preliminary data to remove filters
my js code :
let result = companies;
result.map((item, i) => {212
let rows = [...result[i].table.table_rows].filter((item3) => {
return Object.keys(item3).some(i => item3[i][key] === value[key]);
});
result[i].table.table_rows = [...rows];
return result[i];
});
arrayFilter(result);
my data is:
{
"companies": [
{
"company": {
"name": "company 1"
},
"table": {
"table_rows": [
{
"cells": {
"product_name": "prod1",
"pa_size": "12"
}
},
{
"cells": {
"product_name": "prod2",
"pa_size": "15"
}
}
]
}
},
{
"company": {
"name": "company 2"
},
"table": {
"table_rows": [
{
"cells": {
"product_name": "prod2-1",
"pa_size": "12"
}
},
{
"cells": {
"product_name": "prod2-2",
"pa_size": "18"
}
}
]
}
}
]
}
I tried many ways to solve this problem, but I did not get the right answer
Your question is not clear, the point I have understand that you wanted to filter the array "table_rows" located inside each companies array object? map and filter returns new array, so the solution for this is:
result = result.companies.map((item, i) => {
const newItem = {...item};
let rows = newItem .table.table_rows.filter((item3) => {
return Object.keys(item3).some(i => item3[i][key] === value[key]);
});
newItem.table_rows = [...rows];
return newItem ;
});
arrayFilter(result);

How to create a JS object and append it to an array

I have the following data :
const data=
{
"1": [
{
"sales_project_id": 5,
"sales_project_name": "name",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
},
{
"sales_project_id": 6,
"sales_project_name": "name2",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
}
],
"2": [],
"4": []
}
These data are grouped in my backend based on their Status , in this case im only showing 2 status , but they are dynamic and can be anything the user defines.
What i wish to do is to transform the above data into the format below :
const data =
{
columns: [
{
id: // id of status here,
title: //label of status here,
cards: [
{
id : //sales_project_id here,
title: //sales_project_name here,
},
]
},
{
id: // id of status here,
title: //label of status here,
cards: [
{
id : //sales_project_id here,
title: //sales_project_name here,
},
]
}
]}
My guess would be to iterate over the data , however i am pretty unfamiliar with doing so , would appreciate someone's help!
Here is what i could come up with so far:
const array = []
Object.keys(a).map(function(keyName, keyIndex) {
a[keyName].forEach(element => {
#creating an object of the columns array here
});
})
after some trial and error , manage to accomplish this , however , im not sure if this is a good method to do so.
Object.keys(projects).map(function(keyName, keyIndex) {
// use keyName to get current key's name
// and a[keyName] to get its value
var project_object = {}
project_object['id'] = projects[keyName][0].id
project_object['title'] = projects[keyName][0].label
project_object['description'] = projects[keyName][0].description
console.log( projects[keyName][1])
var card_array = []
projects[keyName][1].forEach(element => {
var card = {}
card["id"] = element.sales_project_id
card["title"] = element.sales_project_name
card["description"] = element.sales_project_est_rev
card_array.push(card)
});
project_object["cards"] = card_array
array.push(project_object)
})
Im basically manipulating some the scope of the variables inorder to achieve this
See my solution, I use Object.keys like you, then I use reduce:
const newData = { columns: Object.keys(data).map((item) => {
return data[item].reduce((acc,rec) => {
if (typeof acc.id === 'undefined'){
acc = { id: rec.project_status.id, title: rec.project_status.label, ...acc }
}
return {...acc, cards: [...acc.cards, { id:rec.sales_project_id, title:rec.sales_project_name}]}
}, {cards:[]})
})}
See full example in playground: https://jscomplete.com/playground/s510194
I'd just do this. Get the values of data using Object.values(data) and then use reduce to accumulate the desired result
const data=
{
"1": [
{
"sales_project_id": 5,
"sales_project_name": "name",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
},
{
"sales_project_id": 6,
"sales_project_name": "name2",
"sales_project_est_rev": "123.00",
"project_status": {
"id": 1,
"label": "Start",
"description": null
}
}
],
"2": [],
"4": []
};
const a = Object.values(data)
let res =a.reduce((acc, elem)=>{
elem.forEach((x)=>{
var obj = {
id : x.project_status.id,
title : x.project_status.label,
cards : [{
id: x.sales_project_id,
title: x.sales_project_name
}]
}
acc.columns.push(obj);
})
return acc
},{columns: []});
console.log(res)

Lodash extract value from nested object

I have below object which I am currently looping through to get item value. Currently I am using lodash _.forEach to achieve this. I am not sure what is best possible to create a new object with item name as key and value as value.
data = [
{
"panels" : [
{
"title": "Panel 1",
"items" : [
{
"name": item1,
"value": 1
}
{
"name": item2,
"value": 2
}
]
},
{
"title": "Panel 2",
"items" : [
{
"name": item3,
"value": 3
}
{
"name": item4,
"value": 5
}
]
}
]
}
{
"panels" : [
{
"title": "Panel 3"
"items" : [
{
"name": item5,
"value": 5
}
{
"name": item6,
"value": 6
}
]
}
]
}
]
let values = [];
_.forEach(data, (groups) => {
_.forEach(groups.panels, (panel) => {
_.forEach(panel.items, (item) => {
values[item.name] = item.value;
});
});
});
return values;
Is there any other way I can achieve this in more efficient way ?
You could use a nested for...of loops with destructuring
const data=[{panels:[{title:"Panel 1",items:[{name:"item1",value:1},{name:"item2",value:2}]},{title:"Panel 2",items:[{name:"item3",value:3},{name:"item4",value:5}]}]},{panels:[{title:"Panel 3",items:[{name:"item5",value:5},{name:"item6",value:6}]}]}];
const output = {};
for (const { panels } of data)
for (const { items } of panels)
for (const { name, value } of items)
output[name] = value;
console.log(output)
Or,
You could use a chained flatMap to get an array of items. Then reduce the items array to get an object with name as key and value as it's value
const data=[{panels:[{title:"Panel 1",items:[{name:"item1",value:1},{name:"item2",value:2}]},{title:"Panel 2",items:[{name:"item3",value:3},{name:"item4",value:5}]}]},{panels:[{title:"Panel 3",items:[{name:"item5",value:5},{name:"item6",value:6}]}]}];
const output = data.flatMap(o => o.panels)
.flatMap(p => p.items)
.reduce((acc, o) => ({ ...acc, [o.name]: o.value }), {})
console.log(output)

Javascript nested .map() returning multiple arrays

Given that I have a JSON structure like this:
{
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever"
}]
}]
}]
}
And I need to map from thirdData value === "whatever"
So I am doing
const result = firstData.map(first => {
return first.secondData.map(second => {
return second.thirdData.map(third => {
return third.value === 'whatever';
});
});
});
And this works somewhat fine, but the result is a another deeply nested array (like [ [ [ {results..} ] ] ]). I know I can flatten this to a single array by other means, but I feel like I am miss using .map(). How can I modify this result to a single array that contains the values of thirdData where the value is what ever I want?
The desired result for this would be a single array of thirdData objects:
[{ value: 'whatever'}, ... {n}]
You can use Array#reduce for reducing into a single value(in this case single array) and Array#forEach for iterating over the nested array.
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever"
}]
}]
}]
}
const result = data.firstData.reduce((arr, first) => {
// iterate over the second level array
first.secondData.forEach(second => {
// iterate over the third level array
second.thirdData.forEach(third => {
// push the value into the result array,
// change here, in case you want the value
//arr.push(third.value === 'whatever');
// in case you need the object then do it like
if(third.value === 'whatever') arr.push(third);
});
});
// return the array reference for the next iteration
return arr;
// set the initial value as an array for the result
}, []);
console.log(result);
If you want a flat result, this isn't a use case for map. The simple solution is just to use an array you close over and push to:
const result = [];
firstData.forEach(first => {
return first.secondData.forEach(second => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
});
});
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = [];
data.firstData.forEach(first => {
return first.secondData.forEach(second => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
});
});
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
Note the filter on the thirdData and using spread notation to push that data into result.
That assumes you want the entry from thirdData that has .value === 'whatever' rather than a true/false. If you want the true/false instead, change that filter to map.
Or the for-of equivalent:
const result = [];
for (const first of firstData) {
for (const second of first.secondData) {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
}
}
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = [];
for (const first of data.firstData) {
for (const second of first.secondData) {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
}
}
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
(Same note about filter/map.)
As with all array operations, you can shoehorn this into reduce, and I guarantee you you'll get answers primarily using reduce, but there's no good reason to use reduce here.
const result = firstData.reduce((result, first) => {
return first.secondData.reduce((result, second) => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
return result;
}, result);
}, []);
Again, though, there's no good reason for that. It's just more complicated.
Live Example with a slight extension to your minimal provided data:
const data = {
"firstData": [{
"secondData": [{
"thirdData": [{
"value": "whatever",
"label": "third #1.1"
},
{
"value": "whatever",
"label": "third #1.2"
},
{
"value": "unrelated",
"label": "unrelated"
}
]
}]
},
{
"secondData": [{
"thirdData": [{
"value": "another unrelated"
},
{
"value": "whatever",
"label": "third #2"
}
]
}]
}
]
};
const result = data.firstData.reduce((result, first) => {
return first.secondData.reduce((result, second) => {
result.push(...second.thirdData.filter(third => third.value === 'whatever'));
return result;
}, result);
}, []);
console.log(result);
.as-console-wrapper {
max-height: 100% !important;
}
(Same note about filter/map.)

How i can get data from another object?

Plunker
I have two structures - ingredients and recipes
[{
"id":"1",
"name": "Cucumber"
},
..
]
and
[{
"id":"1",
"name": "Salad1",
"recipein":[1, 3, 5]
}, {
...
}
]
and i want to show names of ingredients in each salad by press a button.
I filtered object to get ID of object, then i try to get a array of ingredients
getSalad(param:number) {
this.saladId = this.recipe.filter(rec => {
return rec.id.includes(param);
})
this.getNameOfIngredients(this.saladId)
}
getNameOfIngredients(saladArray:any) {
var ingredientsId = saladArray.map(function(num) {
return num.recipein;
});
i getting array [1,2,4] now i want to show all names of ingredients from this.ingredients with this array of id's.
How can i do this?
Plunker
I made updates in your plunker. I think thats what are you looking for: Plunker
getSalad(param:number) {
this.saladId = this.recipe.filter(rec => +rec.id === param )[0];
if(!this.saladId){
this.currentSalad = "Salad not found";
return;
}
this.currentSalad = this.getNameOfIngredients(this.saladId)
}
getNameOfIngredients(saladArray:any) {
return this.ingredients.filter( ing => {
return saladArray.recipein.indexOf(+ing.id) !== -1;
});
let _ingredients = []
this.ingredients.foreach((ingr)=>{
if(this.ingreIDArry.indexof(ingr.id) > -1){
_ingredients.push(ingr.name)
}
})
return _ingredients
is this what you want?
if you can flatten the array, it would be very straightforward for us to do lookups.
Here is what you could do.
const salads = [{
"id": "1",
"name": "Salad1",
"recipein": [1, 3, 5]
}];
const ingredients = [{
"id": "1",
"name": "Cucumber"
},
{
"id": "2",
"name": "Cucumber2"
},
{
"id": "3",
"name": "Cucumber3"
},
{
"id": "4",
"name": "Cucumber4"
},
{
"id": "5",
"name": "Cucumber5"
}
];
const flattenIngredients = (() => {
const output = {};
ingredients.forEach((ingredient) => {
output[ingredient.id] = ingredient;
});
return output;
})();
const getSalad = (saladId) => {
const filteredSalad = salads.filter((salad) => {
return saladId == salad.id;
});
if (filteredSalad.length > 0) {
const salad = filteredSalad[0];
return salad.recipein.map((receip) => flattenIngredients[receip].name);
}
}
console.log(getSalad(1));

Categories

Resources