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);
Related
I need to be able to evaluate (True/False) some conditions not using Eval method. I came across this awesome technique which suits my needs: https://stackoverflow.com/a/68822307/9481833
Now I am trying to implement something like a Like operator and found the test function. Tried to amend the example as per the below but no joy:
const conditionalArray = [
{ name: "fridge", condition: "like", value: "sam" },
];
const dataTofilter = [
{ line: "Blah", revene: 3, sale: 2, fridge: "samsung" },
];
const conditions = {
'like': (x, y) => x.test(/y/),
};
const result = dataTofilter.filter(data => {
for (const el of conditionalArray) {
if (!conditions[el.condition](data[el.name], el.value)) {
return false;
}
}
return true;
});
console.log(result);
Error message is that 'test' is not a function. Perhaps I'll need to handle this case in the filter codeblock at the bottom and look for the 'like' operator and handle it there ?
Therefore you should use match. I also fixed your like function so it won't match /y/ the literal but rather y the variable. Note: it needs escaping for RegExp.
const conditionalArray = [{
name: "fridge",
condition: "like",
value: "sam"
}, ];
const dataTofilter = [{
line: "Blah",
revene: 3,
sale: 2,
fridge: "samsung"
}, ];
const conditions = {
'like': (x, y) => x.match(new RegExp(y)),
};
const result = dataTofilter.filter(data => {
for (const el of conditionalArray) {
if (!conditions[el.condition](data[el.name], el.value)) {
return false;
}
}
return true;
});
console.log(result);
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 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);
I am trying to categorise the objects by comparing two objects say data and categories
const data = {
"1a": {
"name": "1a",
"count": 154
},
"1b": {
"name": "1b",
"count": 765
},
"1c": {
"name": "1c",
"count": 7877
},
"777": {
"name": "777",
"count": 456
}
};
const categories = {
"A_category":["A","1a", "2a"],
"B_category":["1b", "2b"],
"C_category":["1c", "2c"],
"D_category":["1d", "2d"]
};
I want to group the data based on the category object, when there is no match the group should be others and the resultant data should be like
const resultData = [
{ group: 'Others', name: '777', count: 456 },
{ group: 'A_category', name: '1a', count: 154 },
{ group: 'B_category', name: '1b', count: 765 },
{ group: 'C_category', name: '1c', count: 7877 }
]
I used the function but not able to achieve the result
const resultData = [];
function restructure(data, categories) {
Object.keys(data).map(
dataKey => {
for (let [key, value] of Object.entries(categories)) {
value.includes(dataKey) ? resultData.push({"group": key,...data[dataKey]}) : resultData.push({"group": "Others",...data[dataKey]}) ;
break;
}
}
)
}
restructure(data,categories);
You can try this as well. Iterate over your data entries and find whether the key exists in any of the categories object data and push it into the array with found category as group or push it with Others as group as shown in the below code
const data = {
"1a": {
"name": "1a",
"count": 154
},
"1b": {
"name": "1b",
"count": 765
},
"1c": {
"name": "1c",
"count": 7877
},
"777": {
"name": "777",
"count": 456
}
};
const categories = {
"A_category": ["A", "1a", "2a"],
"B_category": ["1b", "2b"],
"C_category": ["1c", "2c"],
"D_category": ["1d", "2d"]
};
const resultData = [];
Object.entries(data).map(([key, val])=>{
let group = Object.keys(categories).find(category=>categories[category].includes(key)) || 'Others'
resultData.push({
group,
...val
})
})
console.log(resultData)
Instead of for loop you need to use filter as let category = Object.entries(categories).filter(([key, value]) => value.includes(dataKey));.
If category.length > 0 then category is available else use Others.
Try it below.
const data = {
"1a": {
"name": "1a",
"count": 154
},
"1b": {
"name": "1b",
"count": 765
},
"1c": {
"name": "1c",
"count": 7877
},
"777": {
"name": "777",
"count": 456
}
};
const categories = {
"A_category": ["A", "1a", "2a"],
"B_category": ["1b", "2b"],
"C_category": ["1c", "2c"],
"D_category": ["1d", "2d"]
};
const resultData = [];
function restructure(data, categories) {
Object.keys(data).map(
dataKey => {
let category = Object.entries(categories)
.filter(([key, value]) => value.includes(dataKey));
resultData.push({
"group": category.length > 0 ? category[0][0] : "Others",
...data[dataKey]
});
})
}
restructure(data, categories);
console.log(resultData);
That's because you're breaking out of the loop regardless of whether you found the category or not. Your for loop will only execute once then breaks immediately. If the first category object matches, it is used, if not "Others" is assigned and the loop exits without checking the rest of the categories. Only break out of the loop if the lookup is successful:
for (let [key, value] of Object.entries(categories)) {
if(value.includes(dataKey)) { // if this is the category
resultData.push({ "group": key, ...data[dataKey] }); // use it ...
return; // ... and break the loop and the current iteration of forEach. The current object is handled
}
}
resultData.push({ "group": "Others", ...data[dataKey] }); // if the return statement above is never reached, that means the category was not found, assign "Others"
BTW, you can use other array methods to shorten things out like so:
function restructure(data, categories) {
return Object.keys(data).map(key => ({
"group": Object.keys(categories).find(cat => categories[cat].includes(key)) || "Others",
...data[key]
}));
}
Then use like so:
const resultData = restructure(data, categories);
My method uses find to try to find a category key that contains the name of the object, if find fails, it returns null at which point, the || "Others" part is evaluated and "Others" will be used as the group name (Does JavaScript have "Short-circuit" evaluation?).
Demo:
const data = {"777":{"name":"777","count":456},"1a":{"name":"1a","count":154},"1b":{"name":"1b","count":765},"1c":{"name":"1c","count":7877}};
const categories = {"A_category":["A","1a","2a"],"B_category":["1b","2b"],"C_category":["1c","2c"],"D_category":["1d","2d"]};
function restructure(data, categories) {
return Object.keys(data).map(key => ({
"group": Object.keys(categories).find(cat => categories[cat].includes(key)) || "Others",
...data[key]
}));
}
const resultData = restructure(data, categories);
console.log(resultData);
I am trying to filter through an array of objects to find all values with an image extension then push the values found into their own array.
Example: imageArray = ["steve.jpg", "funimage1.jpg", "coolimage2.png","greatimage3.svg", "jimmysavatar.jpg" ...].
Here is a jsfiddle to test: https://jsfiddle.net/25pmwsee/
const myArray = [{
"prepend": false,
"name": "steve",
"avatar": "steve.jpg",
"imgs": [
"funimage1.jpg",
"coolimage2.png",
"greatimage3.svg"
]
},
{
"prepend": false,
"name": "jimmy",
"avatar": "jimmysavatar.jpg",
"imgs": [
"realimage1.jpg",
"awesomeimage2.png",
"coolimage3.svg"
]
}]
const extensions = [".jpg", ".png", ".svg"];
let imageArray = [];
// search in array for extension then push key to array
for (let i = 0; i < extensions.length; i++) {
if ( extensions[i] in myArray ) {
imageArray.push(image)
}
}
Try this, I iterate through object and check if object has property as object then iterate through it and add if find any image.
const myArray = [{
"prepend": false,
"name": "steve",
"avatar": "steve.jpg",
"imgs": [
"funimage1.jpg",
"coolimage2.png",
"greatimage3.svg"
]
},
{
"prepend": false,
"name": "jimmy",
"avatar": "jimmysavatar.jpg",
"imgs": [
"realimage1.jpg",
"awesomeimage2.png",
"coolimage3.svg"
]
}]
const extensions = [".jpg", ".png", ".svg"];
let imageArray = [];
// search in array for extension then push key to array
function iterate(obj){
for(var x in obj){
//console.log(typeof(obj[x]));
if(typeof(obj[x])==='object'){
iterate(obj[x]);
}
else if (obj.hasOwnProperty(x)){
extensions.forEach(function(e){
if(typeof(obj[x])==='string' && obj[x].endsWith(e))
imageArray.push(obj[x]);
})
}
}
}
myArray.forEach(function(x){iterate(x)})
console.log(imageArray);
// regular expression to match a file extension and capture it
const extensionRegex = /\.([a-z]+)$/
// map of allowed extensions; indexing by any not listed will be falsy (undefined)
const allowedExtensions = {
'jpg': true,
'png': true,
'svg': true
}
// grab each user's avatar
let avatars = myArray.map(function (user) {
return user.avatar
})
// takes all the imgs arrays and flatten them down to an array of strings
let imgs = myArray.map(function (user) {
return user.imgs
}).reduce(function (flattened, images) {
return flattened.concat(images)
}, [])
avatars.concat(imgs).forEach(function (imageName) {
// if imageName is undefined or empty, use empty string instead
// since we know that will fail the allowedExtensions check and not push
let extension = (imageName || '').match(extensionRegex)[1]
if (allowedExtensions[extension]) {
imageArray.push(imageName);
}
});
Some reference links:
How do you access the matched groups in a JavaScript regular expression?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce