I have some data samples stored in a variable data_ as below.
[{'Age': 39, 'count': 5}, {'Age': 24, 'count': 5}]
So I have this javascript list as below:
barChartData(data) {
const datum = [
{
values: [
{
label: "A",
value: -29.765957771107,
color: "#3ebfea",
},
],
},
];
return datum;
}
// and use it
barChartData(data_) // passing the data sample to the function
And now what I want to do is, change the keys in the datum inside function with the data_ I pass.
so it will look like this:
barChartData(data) {
const datum = [
{
values: [
{
label: "Age",
value: <Age-received-from-data-parameter>,
color: "#3ebfea",
},
],
},
];
return datum;
}
How can I iterate/map the data inside the barChartData function and assign the value
I tried but I it is not working and I am pretty sure something is missing.
Can someone help me do this?
This is I what I tried
barChartData(data) {
const datum = [
{
// key: "Cumulative Return",
values: [
data.map((emp, index) =>
{ // below gives syntax errors
label: "Age",
value: emp.Age,
color: "#3ebfea",
}
)
],
},
];
return datum;
}
First, map function already returns an array, and it seems there's no need to wrap it into [] once more. Second, when arrow function returns an object, it should be wrapped into () to avoid confusing the parser. So here's one way your function might look like:
const source = [{
'Age': 39,
'count': 5
}, {
'Age': 24,
'count': 5
}];
// ----------------
function barChartData(data) {
const datum = [{
// key: "Cumulative Return",
values: data.map(emp => ({ // note `(` wrapper
label: "Age",
value: emp.Age,
color: "#3ebfea",
}))
}];
return datum;
}
console.log(barChartData(source));
Related
say that I receive this JSON array from an API call.
[
"{'apple': 'enabled'}",
"{'banana': 'disabled'}"
]
How do I transform it into this:
[
{
label: 'apple',
value: 'enabled'
},
{
label: 'banana',
value: 'disabled'
}
]
The number of fields and the values are of course variable.
With JSON5.parse() I can transform it into this:
[
{
apple: 'enabled',
},
{
banana: 'disabled'
}
]
But this is still not what I need.
How can I achieve the transformation I need, without hacky workarounds that might change the values inside?
Thank you
const apiArray = [
"{'apple': 'enabled'}",
"{'banana': 'disabled'}"
];
const returnArray = [];
for (const element of apiArray) {
const parsedObj = JSON.parse(element);
const label = Object.keys(element)[0];
const value = parsedObj[label];
returnArray.push({"label": label, "value": value});
}
This inspects every element of the initial array on its own and extracts the label and the value. These then get pushed into the returnArray in the correct format.
I managed to make it work with this:
(Thanks #Alexander)
data.map(el=>{
const parsed = JSON5.parse(el)
return{
label: Object.keys(parsed)[0],
value: Object.values(parsed)[0]
}
})
However, it is not very clean.
you can try this
var newArr = [];
apiArray.forEach((element) => {
let obj = JSON.parse(element.replaceAll("'", '"'));
newArr.push({ label: Object.keys(obj)[0], value: Object.values(obj)[0] });
});
console.log(JSON.stringify(newArr));
you can try something like this :
myArray.map((data) => {
const parsedData = JSON.parse(data);
return {
label: Object.keys(parsedData).join(),
value: Object.values(parsedData).join(),
};
});
Output :
[{
"label": "apple",
"value": "enabled"
},
{
"label": "banana",
"value": "disabled"
}]
I have add my all code below, but important function is patchDataCollection() where i have added push logic for forms.
I want to compare values of both arrayOne and arrayTwo based on below condition and if it matches than it will pass data along with form otherwise it will create an empty form.
Expected output
I have created patchDataCollection() function where i am creating forms based on above condition, but in my case it is patching data to all generated forms
, i want only patch thosa object which are avlbl in arrayTww.
Below condition i wanted to check in arrayOne and arrayTwo.
if arrayOne processTypeId is equal to arrayTwo of makeProcessTypeId And
arrayOne makeLineName is equal to arrayTwo of makeLineName And
arrayOne processTechType is equal to arrayTwo of processTechType than
If all above conditions are met than only dataOne variable will pass along with form.
this.itemTypes().push(this.createContinuousForm(item, dataOne));
else it will create an empty form only without pushing dataOne in form.
this.itemTypes().push(this.createContinuousForm(item));
Const arrayOne = [
{
"makeLineName": "Red",
types : [
{
"processTypeId": 101,
"processTechType": "Batch"
},
{
"processTypeId": 102,
"processTechType": "Batch"
}
]
},
{
"makeLineName": "Blue",
types : [
{
"processTypeId": 103,
"processTechType": "Continuous"
},
{
"processTypeId": 104,
"processTechType": "Batch"
}
]
}
];
Const arrayTwo =
[
{
"makeProcessTypeId": 101,
"makeLineName": "Red",
"processTechType": "Batch",
"avgBct": 23,
"bestBct": 23
},
{
"makeProcessTypeId": 102,
"makeLineName": "Blue",
"processTechType": "Batch",
"avgBct": 45,
"bestBct": 45
},
{
"makeProcessTypeId": 103,
"makeLineName": "Blue",
"processTechType": "Continuous",
"designProcessCapacity": 250,
"minRunLength": 250
}
];
getMakeLineData() {
for (const line of arrayOne) {
const list = line.types;
for (const item of list) {
if (item.processTechType === 'Continuous') {
this.patchDataCollection(item);
} else if (item.processTechType === 'Batch' || item.processTechType === 'Batch-Crunch') {
this.patchDataCollection(item);
}
}
}
}
patchDataCollection(arrayOne) {
if (arrayTwo) {
for (const dataOne of arrayTwo) {
if (arrayOne.makeLineName == dataOne.makeLineName) {
if (arrayOne.processTechType === 'Continuous') {
this.itemTypes().push(this.createContinuousForm(item, dataOne));
}
if (dataOne.processTechType === 'Batch' || dataOne.processTechType === 'Batch-Crunch') {
this.itemTypes().push(this.createBatchForm(item, dataOne));
}
}
}
}
}
createContinuousForm(type, data) {
return this.fb.group({
makeLineName: [type.makeLineName],
processTechType: [type.processTechType],
makeProcessTypeId: [type.processTypeId],
designProcessCapacity: [data.designProcessCapacity ? data.designProcessCapacity : '', [Validators.required]],
minRunLength: [data.minRunLength ? data.minRunLength : '']
});
}
createBatchForm(type, data) {
return this.fb.group({
makeLineName: [type.makeLineName],
processTechType: [type.processTechType],
makeProcessTypeId: [type.processTypeId],
avgBct: [data.avgBct ? data.avgBct : '', [Validators.required]],
bestBct: [data.bestBct ? data.bestBct : '', [Validators.required]]
});
}
itemTypes(): FormArray {
return this.dataCollectionForm.get("items") as FormArray;
}
While I think there are better ways to store the data compared to what the API returns to you, it is certainly possible to compare the two arrays and only use the values that exist in both arrays, given your conditions.
The surrounding object with makeLineName and types in your arrayOne do not contain any valuable information (any information that is not within the types array anyway). You can start here with:
arrayOne.flatMap(i => i.types)
From my perspective the createContinuousForm and createBatchForm functions don't need two parameters. It should be enough if you pass the item from arrayTwo as the only values from arrayOne used in your functions are the one that must match the ones from arrayTwo.
I could see something in this direction working:
const arrayOne = [{
makeLineName: 'Red',
types: [{
processTypeId: '102',
processTechType: 'Batch',
makeLineName: 'Red',
}, ],
},
{
makeLineName: 'Blue',
types: [{
processTypeId: '103',
processTechType: 'Continuous',
makeLineName: 'Blue',
}, ],
},
];
const arrayTwo = [{
makeProcessTypeId: 101,
makeLineName: 'Red',
processTechType: 'Batch',
avgBct: 23,
bestBct: 23,
},
{
makeProcessTypeId: 102,
makeLineName: 'Blue',
processTechType: 'Batch',
avgBct: 45,
bestBct: 45,
},
{
makeProcessTypeId: 103,
makeLineName: 'Blue',
processTechType: 'Continuous',
designProcessCapacity: 250,
minRunLength: 250,
},
];
const simplifiedArrayOne = arrayOne.flatMap(i => i.types);
function createContinuousForm(item) {
console.log({
// if you put this into [], then your makeLineName is an array with one value
makeLineName: item.makeLineName,
processTechType: item.processTechType,
makeProcessTypeId: item.makeProcessTypeId,
designProcessCapacity: [
item.designProcessCapacity ? item.designProcessCapacity : ''
],
});
}
function createBatchForm(item) {
console.log({
makeLineName: item.makeLineName,
processTechType: item.processTechType,
makeProcessTypeId: item.makeProcessTypeId,
avgBct: item.avgBct ? item.avgBct : '',
bestBct: item.bestBct ? item.bestBct : '',
});
}
arrayTwo.filter(entry => {
// .toString() is necessary because your types of processTypeId (string) and makeProcessTypeId (number) are different
const index = simplifiedArrayOne.findIndex(e => e.processTypeId === entry.makeProcessTypeId.toString())
return index > -1 && entry.makeLineName === simplifiedArrayOne[index].makeLineName
}).forEach(item => item.processTechType === 'Continuous' ? this.createContinuousForm(item) : this.createBatchForm(item));
Please take note of the comments within the code. Also, as you're using TypeScript you could use an enum for the processTechType and possibly another one for the makeLineName as well
I have the following two simple objects:
clinics: [
{
id: 1,
name: 'New Hampshire Veterinarian Clinic',
plans: [
'handle123',
'handle567',
]
},
{
id: 2,
name: 'Westminster Moltchester Clinic',
plans: [
'handle123',
'handle789',
]
}
],
animals: [
{
id: 1,
handle: 'handle123',
name: 'Cat',
},
{
id: 2,
handle: 'handle567',
name: 'Dog',
},
{
id: 3,
handle: 'haneld789',
name: 'Horse'
}
],
I have the following method:
updateAnimals(selectedOption, id) {
}
where selectedOption is one object from the clinics array.
I want to filter the second array so it only contains the handles mentioned in the selected option, but I'm having trouble with the arguments. I want to achieve something like this:
updateAnimals(selectedOption, id) {
let filteredAnimals = this.animals.filter(function({id, handle, name}) {
// Access the selectedOption here so I can use it to filter
});
}
But I'm not sure how to access the selected option inside the function...
Or is there a better way to do that?
You can use selectedOption just like any other variable available in a scope by simply using it directly selectedOption.something:
updateAnimals(selectedOption, id) {
let filteredAnimals = this.animals.filter({ handle } => {
return selectedOption.plans.includes(handle)
});
}
updateAnimals(selectedOption, id) {
const handles=selectedOption.plans;
let result= animals.filter(animal=>handles.includes(animal.handle));
}
how to assign the object in object and filter the value which pass and fail;
the input is:
[
{
name: 'John',
score: 90,
time: 'evening'
},
{
name: 'Doni',
score: 68,
time: 'morning'
},
{
name: 'Jiu',
score: 50,
time: 'evening'
},
{
name: 'Shin',
score: 92,
time: 'morning'
},
];
and i want the output like this :
{
"evening": {
"pass": [
{
"name": "John",
"score": 90
}
],
"fail": [
{
"name": "jiu",
"score": 50
}
]
},
"morning": {
"pass": [
{
"name": "Shin",
"score": 92
}
],
"fail": [
{
"name": "Doni",
"score": 68
}
]
}
}
do we need to use Object.assign for this ? and how many loop we use for this ??
i do love to know how to add another string in the object beside that ouput,
thanks
There's a lot of ways to do this. The simplest is probably to make a base object that represent your empty results. Then loop over the students and fill the arrays:
let students = [{name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];
// Empty case
let base = {
"evening": {"pass": [], "fail": []},
"morning": {"pass": [], "fail": []}
}
const PASSING = 70
students.forEach(({name, score, time}) => {
let key = score >= PASSING ? 'pass' : 'fail'
base[time][key].push({name, score})
})
console.log(base)
This makes is easy to have empty arrays, which is probably what you want if there are no students in a particular category.
EDIT based on comment:
To support arbitrary times, you can just create the times on the object as you find them. reduce() is good for this, but you could also use a regular loop. For example with an added afternoon time:
let students = [{name: 'Mark',score: 95,time: 'afternoon'}, {name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];
const PASSING = 70
let result = students.reduce((obj, {name, score, time}) => {
if (!obj[time]) obj[time] = {'pass': [], 'fail': [] }
let key = score >= PASSING ? 'pass' : 'fail'
obj[time][key].push({name, score})
return obj
}, {})
console.log(result)
You can do something like this:
const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];
const grp = (d, p) => d.reduce((r,c) => (r[c[p]] = [...r[c[p]] || [], c], r), {})
const grpV = (d, rng) => d.reduce((r,{name, score}) => {
let key = score > rng ? 'pass' : 'fail'
r[key] = [...r[key] || [], {name, score}]
return r
}, {})
const r = Object.entries(grp(data, 'time')).map(([k,v]) => ({[k]: grpV(v, 75)}))
console.log(r)
The idea is the group 2 times one on the time and 2nd on the score.
grp: function to group by a property (in this case 'time') which returns an object with 2 properties: evening and morning each of which is an array containing the classes.
grpV: function to group by value (in this case 75) which returns an object with 2 properties: pass and fail each of which is an array containing the classes.
On the end once we have those tools we are saying ... give me the entries of the grouped by time object and for each of the groups ... group by score.
Here how something like this could look like if we ware using lodash:
const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];
const partition = (x, p) => _(x)
.partition(y => y.score > p)
.map((x,i) => ({ [i==0 ? 'pass': 'fail']: _.omit(x[0], 'time')}))
.value()
const r = _(data)
.groupBy('time')
.mapValues(x => partition(x, 75))
.value()
console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Adding it as an example since it does help with readability of what the ES6 example is doing to some extend.
I'm sure there are more elegant ways to do this. But this one is probably one of the simplest beginner-friendly ways you can go about this.
I loop through the input array, check the existence of the .time values as keys on the output object and create the pass and fail keys. Then evaluate the .score against the passingScore and push the necessary data to it.
Should be pretty easy to understand once you see and try the code below:
const data = [
{name: 'John',score: 90, time: 'evening'},
{name: 'Doni',score: 68, time: 'morning'},
{name: 'Jiu',score: 50, time: 'evening'},
{name: 'Shin',score: 92, time: 'morning'},
{name: 'Fubar',score: 75, time: 'noon'},
];
function formatData(data){
const passingScore = 75;
const output = {};
data.forEach(function(item){
if(!output[item.time]) output[item.time] = {pass: [], fail: []};
const stud = { name: item.name, score: item.score };
if(item.score >= passingScore) output[item.time]['pass'].push(stud)
else output[item.time]['fail'].push(stud)
});
return output;
}
console.log(formatData(data));
I have an array with objects I want to search through. The searchable array looks like this:
[
{ value: 0, label: 'john' },
{ value: 1, label: 'johnny' },
{ value: 2, label: 'peter' },
{ value: 3, label: 'peterson' }
]
I search through this using the Lodash filter method:
search = (text) => {
let results = _.filter(
this.props.options,
{ label: text }
);
}
This only shows the result that exactly matches the search query (text parameter). I need to make this work with partial matches. So if I insert j or johnny it should be able to find both 'John' and 'Johnny'.
I have tried:
search = (text) => {
let results = _.filter(
this.props.options =>
this.props.options.includes({ label: text })
);
}
But, no luck. No error and no results. How can I make this work?
Since you are using includes which is a part of ES6 standat, then I would solve this task with the ES6 Array.prototype.filter instead of lodash-filter:
let search = (list, text) =>
list.filter(i => i.label.toLowerCase().includes(text.toLowerCase()));
let list = [
{ value: 0, label: 'john' },
{ value: 1, label: 'johnny' },
{ value: 2, label: 'peter' },
{ value: 3, label: 'peterson' }
];
let result = search(list, 'j');
console.log(result); // [{value: 0, label: "john"}, {value: 1, label: "johnny"}]
Also, with .toLowerCase you may use "John" instead of "john".
String#includes accepts a string as a needle. If the the needle is not a string, it's converted to string, and it the case of an object it's [object Object].
You should get the value of label, and use the string's includes method:
const options = [
{ value: 0, label: 'john' },
{ value: 1, label: 'johnny' },
{ value: 2, label: 'peter' },
{ value: 3, label: 'peterson' }
];
const search = (text) => options.filter(({ label }) => label.includes(text));
const result = search('jo');
console.log(result);
That's not how you use String.prototype.includes. You should provide a string to it not an object. And you should provide a function that wraps the call to includes:
search = (text) => {
let results = _.filter(
this.props.options, // first parameter to _.filter is the array
option => option.label.includes(text) // the second parameter is a funtion that takes an option object and returns a boolean (wether the label of this option includes the text text or not)
);
}