I want to write a forEach function for finding out data in my JSON
Case:
[[{ {"Plan-Name = "qwe" , "plan_data" = "10"}
{"Plan-Name = "asd" , "plan_data" = "10"}
{"Plan-Name = "wrt" , "plan_data" = "10"}
}]]
I want to search wrt and print its plan_data
and I have a Current plan = wrt, so if the current plan matches with Plan_name then print its Plan_data
I for my current plan responseJson[0][0]['cuurent_plan']
and for Plan_name responseJson[2]
It seems the JSON is invalid, if it's a valid JSON then you can do as below for your desired result.
const getPlanData = (planData, planName: string) => {
const planInfo = planData.find((plan) => plan["Plan-Name"] === planName);
return planInfo;
}
const apIResponse = [[
{ "Plan-Name": "qwe", "plan_data": "11" },
{ "Plan-Name": "asd", "plan_data": "22" },
{ "Plan-Name": "wrt", "plan_data": "33" }
]
]
const planValue = getPlanData(apIResponse[0], 'wrt')
console.log('res', planValue);
Related
I am trying to filter a Javascript array of objects with nested objects with specific properties. I can filter the name, slug, website, launch year without any issues. But, I can not filter the category name (category.name) which is an object within the object. Why is filtering the category name not working?
var search = "qui"; // does not work (category.name)
// var search = "Sauer"; // works (name)
var data = [{ "name": "Sauer-Metz", "slug": "ab-laborum",
"website": "https://test.com", "launch_year": 2017, "category_id": 6,
"category": { "id": 6, "name": "qui", "slug": "qui" } } ];
var results = data.filter(company => [
'name', 'launch_year', 'website', 'category.name'
].some(key => String(company[key]).toLowerCase().includes(search.toLowerCase())));
console.log(results);
One way you can go about it is to have a value extractor like the one getKey below
const getKey = (value, key) => {
return key.split('.').reduce((acc, curr) => value[curr], '');
}
var results = data.filter(company => [
'name', 'launch_year', 'website', 'category.name'
].some(key => String(getKey(company, key)).toLowerCase().includes(search.toLowerCase())));
I believe you have to do a separate condition for this specific nested property, although there might be a cleaner way I don't see right now:
var results = data.filter(
(company) =>
["name", "launch_year", "website"].some((key) =>
String(company[key]).toLowerCase().includes(search.toLowerCase())
) ||
String(company["category"]["name"])
.toLowerCase()
.includes(search.toLowerCase())
);
Dot notation doesn't work like that.
const testCase1 = 'qui';
const testCase2 = 'Sauer';
const data = [
{
name: 'Sauer-Metz',
slug: 'ab-laborum',
website: 'https://test.com',
launch_year: 2017,
category_id: 6,
category: { id: 6, name: 'qui', slug: 'qui' },
},
];
const searchResults = (data, search) => {
return data.filter((item) => {
return (
item?.category?.name.toLowerCase().includes(search.toLowerCase()) ||
['name', 'launch_year', 'website'].some((key) => `${item[key]}`.toLowerCase().includes(search.toLowerCase()))
);
});
};
console.log('**CASE 1**')
console.log(searchResults(data, testCase1));
console.log('**CASE 2**')
console.log(searchResults(data, testCase2));
To use your approach you can convert 'category.name' to ['category','name'] and then use String(company[key[0]][key[1]])... whenever key is an array.
const search = "qui"; // does not work (category.name)
//const search = "Sauer"; // works (name)
const data = [{ "name": "Sauer-Metz", "slug": "ab-laborum", "website": "https://test.com", "launch_year": 2017, "category_id": 6, "category": { "id": 6, "name": "qui", "slug": "qui" } } ];
const results = data.filter(
company => [
'name', 'launch_year', 'website', ['category','name']
].some(
key =>
Array.isArray(key) ?
String(company[key[0]][key[1]]).toLowerCase().includes(search.toLowerCase()) :
String(company[key]).toLowerCase().includes(search.toLowerCase())
)
);
console.log(results);
I wanted to filter out the data. I wanted to check if data on data1 is found on data2 and to check if it has errorMessages. Please check my code below. Is there a better way to do it?
data1
[
{
"ids": "0111",
},
{
"ids": "0222",
},
{
"ids": "0333",
}
]
data2
[
{
"id": "0111",
"errorMessages": [
{
"message": ["sample error message 1"]
}
]
},
{
"id": "0333",
"errorMessages": []
}
]
Code
const output= data1.filter(
(element) => element.ids === data2.find((data) => data).id
);
console.log("output", output);
.find((data) => data) doesn't do anything useful - each item in the array is an object, which is truthy, so that'll always return the first element in the array.
If you did want to .find a matching element in the other array - then a better approach would be to make a Set of the IDs found in the other array first (Set lookup is much quicker - O(1) - than .find, which is O(n)).
You also need to implement the logic to check if the errorMessages is empty.
const data1 = [
{
"ids": "0111",
},
{
"ids": "0222",
},
{
"ids": "0333",
}
]
const data2 = [
{
"id": "0111",
"errorMessages": [
{
"message": ["sample error message 1"]
}
]
},
{
"id": "0333",
"errorMessages": []
}
]
const ids = new Set(
data2
.filter(item => item?.errorMessages.length)
.map(item => item.id)
);
const output= data1.filter(
element => ids.has(element.ids)
);
console.log("output", output);
Without Set, but use Object as the map.
const IDKeys = {};
data2.forEach(data => {
if (data.errorMessages.length){
IDKeys[data.id] = true; // means valid
}
})
const filteredArray = data1.filter(data => IDKeys[data.id]);
This would be only O(n) since accessing key on object is O(1)
I am having difficulties formatting some data. Currently, I receive data in the following structure.
[
{
"q1":"5",
"q2":[
"13",
"12",
],
"q3":"test",
}
]
I essentially need to modify this or even create a new object, that takes the following structure.
[
{
id: 1, //q1
answers: [
{
answer: '5',
},
],
},
{
id: 2, //q2
answers: [
{
answer: '13',
},
{
answer: '12',
},
],
},
{
id: 3, //q3
answers: [
{
answer: 'test',
},
],
},
];
So the id in the above would be obtained by remove the q and getting the number in the first data object. It would then have an answers array that would have an object for each answer.
I have been attempting this but have gotten lost. I don't know if I should use loops, mapping, filters etc. To be honest, the furthest I have got so far is obtaining the keys
var modified = data.map(function(item) {
return Object.keys(item)
})
I have created a JSFiddle where I have been attempting to do this.
Is there any way I can achieve the data I am after?
Many thanks
Please use map function.
const data = {
"q1":"5",
"q2":[
"13",
"12",
],
"q3":"test",
};
const result = Object.keys(data).map(key => {
let item = {id: key.substring(1), answers: []};
if(typeof data[key] === "string")
item.answers.push({answer: data[key]});
else
item.answers = data[key].map(val => ({answer: val}));
return item;
});
console.log(result)
const inputData = [
{
"q1":"5",
"q2":[
"13",
"12",
],
"q3":"test",
}
]
function answerMapper(objVal, id){
return Array.isArray(objVal)
?
{ id, answers: objVal.map(answer => ({ answer }))}
:
{ id, answers: [{answer: objVal }] }
}
function formatObject(obj){
return Object.keys(obj).map((k, i) => answerMapper(obj[k], i+1));
}
const result = inputData.map(obj => formatObject(obj));
// remove flatMap if your inputData has more than one entry
console.log(result.flatMap(x => x));
map over the first element of the data with Object.entries, grab the key and value, create a new answers array and return a new object.
const data = [{
"q1": "5",
"q2": [
"13",
"12",
],
"q3": "test",
}];
const out = Object.entries(data[0]).map(obj => {
const [ key, value ] = obj;
const id = Number(key[1]);
// If the the value is an array
// return a new array of mapped data
// Otherwise return an array containing
// one object
const answers = Array.isArray(value)
? value.map(el => ({ answer: el }))
: [{ answer: value }];
// Return the new object
return { id, answers };
});
console.log(out);
lets create a pure function which accepts the object in the array like so
const processObject = obj => Object.keys(obj).map(id => {
const answer = obj[id];
const answers = Array.isArray(answer) ? answer : [answer]
const answerObjectArray = answers.map(ans => ({
answer: ans
}));
return {
id: +id.substring(1),
answers: answerObjectArray
}
});
const dataArray = [{
"q1": "5",
"q2": [
"13",
"12",
],
"q3": "test",
}];
const output = processObject(dataArray[0]);
console.log(output);
I have the json like follow example, i would like to convert this json map to array for to be able to loop on it.
I use the Object.keys method but I don't know how to have a key => value format for the whole json.
I need to get the keys to make a table I know there is the pipe keyvalue but it's not what I need. or maybe I use it wrong
example json
{
"pays": "UK"
"test": [
[
"123456", // here i want key id
"blabla", // here i want key name
"lorem ipsum" // here i want key type
],
[
"654321",
"ipsum",
"blabla"
]
]
}
components.ts
get() {
this.myService.getUrl().subscribe(data => {
this.myArray = Object.keys(data).map((key) => {
return {
id: key,
name: data[key]
}
}):
}
Please try this
var input: any = {
"pays": "UK",
"test": [
[
"123456", // here i want key id
"blabla", // here i want key name
"lorem ipsum" // here i want key type
],
[
"654321",
"ipsum",
"blabla"
]
]
}
input .test = input.test.map((item: any) => {
return {
id: item[0],
name : item[1],
type : item[2]
}
})
This is one possible solution to transform array of strings into array of JSONs:
let input = {
pays: "UK",
test: [
[
"123456",
"blabla",
"lorem ipsum"
],
[
"654321",
"ipsum",
"blabla"
]
]
};
let result = {};
result.pays = input.pays;
result.test = [];
for (let i = 0; i < input.test.length; i++){
let testEl = input.test[i];
let resultObj = {};
resultObj.id = testEl[0];
resultObj.name = testEl[1];
resultObj.type = testEl[2];
result.test.push(resultObj);
}
console.log(result)
i am not getting expected result in below code just wanted to know if its correct way to add condition in arrow function syntax using expression.
const drugPriceErrors = [99, 85];
Case#1
const messages = [{
settlementCode: "99",
settlementDesc: "test:test"
}]
Case#2
const messages = [{
settlementCode: "77",
settlementDesc: "test"
}
];
Case#3
const messages = [{
settlementCode: "66",
settlementDesc: "test:test"
}]
function validateEntries(messages) {
if (!messages) {
return []
};
let filteredMsg = messages.filter((item) => {
if (!drugPriceErrors.includes(item.settlementCode)) {
item.settlementDesc.includes(":")
} else {
return;
}
});
return filteredMsg;
};
console.log(validateEntries(messages));
expected output
Case#1 output should be
[{
settlementCode: "99",
settlementDesc: "test:test"
}]
Case#2 output should be
[]
Case#3 output
[{
settlementCode: "66",
settlementDesc: "test:test"
}]
As per my understanding, you want to filter in those objects that meet following criteria
SettlementCode should not exist in drugPriceErrors array OR
SettlementDesc should contain :
You can correct your code as following
Firstly, as drugPriceErrors is an array of numbers, convert settlementCode to number using +settlementCode
If condition is evaluated to true i.e. settlementCode exist in drugPriceErrors, return true
Else, return whether settlementDesc contains :
const drugPriceErrors = [99,85];
const messages = [ {settlementCode:"99", settlementDesc: "test:test" }, {settlementCode:"66", settlementDesc: "test:test" },{settlementCode: "77",settlementDesc: "test"}];
function validateEntries(messages) {
if (!messages) {
return []
};
let filteredMsg = messages.filter((item) => {
if (drugPriceErrors.includes(+item.settlementCode)) return true;
else return item.settlementDesc.includes(":");
});
return filteredMsg;
};
console.log(validateEntries(messages));
Additionally, you can also simplify your code as following
const drugPriceErrors = [99,85];
const messages = [ {settlementCode:"99", settlementDesc: "test:test" }, {settlementCode:"66", settlementDesc: "test:test" },{settlementCode: "77",settlementDesc: "test"}];
const result = messages.filter(v => drugPriceErrors.includes(+v.settlementCode) || v.settlementDesc.includes(":"));
console.log(result);