I'm trying to sum the values inside an array depending on which levels they are but with no success for the moment.
Datas I'm working with ( named as the variable totalByLevel ) :
What I want :
Having each total per level inside 1 array, for example : ['total of 3 + 4', 'total of 6 + 7', etc...]
What I tried :
I tried to create an empty array and push the values from 3 + 4 into the array, which is working but not as intented.
Only the last values is kept in the array and all others are erased, if you have a fix for it I would really appreciate any help! Thank you in advance.
component.ts
for (const levelKey in this.totalByLevel ) {
if (this.totalByLevel .hasOwnProperty(levelKey)) {
const key = this.labelName[levelKey];
const value = this.totalByLevel [levelKey][Object.keys(this.totalByLevel [levelKey])[0]];
const value2 = this.labelName[Object.keys(this.totalByLevel [levelKey])[0]];
const value3 = this.totalByLevel [levelKey][Object.keys(this.totalByLevel [levelKey])[1]];
const value4 = this.totalByLevel [levelKey][Object.keys(this.totalByLevel [levelKey])[2]];
this.output_object[key] = value;
this.output_object2[key] = value2;
const sum = [];
if (value4 !== undefined || null) {
sum.push((+value + +value3 + +value4).toFixed(2));
console.log(sum, 'SUM 3');
this.totalPerCat = sum;
} else if (value4 === undefined || null) {
sum.push((+value + +value3).toFixed(2));
console.log(sum, 'SUM 2');
this.totalPerCat = sum;
} else if (value3 === undefined || null) {
sum.push(value);
console.log(sum, 'SUM 1');
this.totalPerCat = sum;
}
console.log(this.totalPerCat);
/* console.log(value3);
console.log(value4);
console.log(+value + +value3 + +value4, 'SUM');*/
}
}
});
Here you go:
const data={
2:{3:"3514.80", 4:"7259.32"},
5:{6:"864941.86", 7:"1076976.54"},
8:{"":"14145.69"},
9:{10:"223835.02", 11:"60978.31", 12:"5554.92"}
}
const result = Object.values(data).map(items => Object.values(items).map(val => Number(val)).reduce((a,b) => a + b, 0))
console.log(result)
You could use the funcitons Object.values() and Array reduce in combination. Try the following
var totalByLevel = {
2: {
3: '3514.80',
4: '7259.32'
},
5: {
6: '864941.86',
7: '1076976.54'
}
};
var sum = Object.values(totalByLevel).reduce((acc, curr) => {
acc.push(String(Object.values(curr).reduce((a, c) => a + Number(c), 0)));
return acc;
}, []);
console.log(sum);
Related
How to get an array after converted by reduce()?
Before convert:
After convert:
newProductsDetail = newProductsDetail.reduce((acc, curr) => {
const { categoryName } = curr
if (!acc[categoryName]) {
acc[categoryName] = []
}
acc[categoryName].push(curr)
return acc
}, [])
I would like get newProductsDetail[categoryName]
Have any way to approach this?
Thanks to all of you!
you can filter it like this
productDetail.filter( detail => { if(detail !== undefined && detail[0] !== undefined) return detail[0].categoryName === myCategory; return false; } )
Set initial value as object and not list as follows if you want to get hold of value from newProductsDetail[categoryName]:
newProductsDetail = newProductsDetail.reduce((acc, curr) => {
const { categoryName } = curr
if (!acc[categoryName]) {
acc[categoryName] = []
}
acc[categoryName].push(curr)
return acc
}, {}) // dictionary/object is initial and not list
If you only want array and some manipulation, try to use map to iterate and convert final output to array of something.
HERE IS MY CODE,
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
function uppercase(subject: string) {
return subject.toUpperCase();
}
let subjects_upppercase = subjects
.map(uppercase)
.toString()
.match(/\d+/g)
.map(function (numbers) {
return parseInt(numbers);
})
.filter(function (number) {
if (number > 65) {
return true;
}
})
.map(function (newarray) {
return newarray;
});
console.log(subjects_upppercase);
I have an array of numbers [70,67,88]
now I want to print names of subjects corresponding to the numbers inside an array.
can someone help with this, please?
here is a solution (I didnt quite get what your requirements where but here you go)
const subjects: string[] = ["Mathemetics-70","Science-67","English-88","Geography-62","ComputerSc-55"];
const pairs = subjects.map(subject => {
const subjectNumber = subject.match( /\d+/);
if (!subjectNumber) return undefined;
return [parseInt(subjectNumber[0]), subject.toUpperCase()]
}).filter(Boolean)
const obj = Object.fromEntries(pairs);
console.log(obj); // this will be { number: subject }
// and if you want to print only your numbers use
const toPrint = [70,67,88];
for (let numberToPrint of toPrint){
console.log(obj[numberToPrint]);
}
It is my solution, the code is:
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
const str = subjects.join("\n");
const arr = [70, 67, 88].map((num) => {
return str.match(new RegExp("(\\w+\-)" + num))[0];
});
console.log(arr);
// ['Mathemetics-70', 'Science-67', 'English-88']
I am trying to prepare a table with dynamic rowspan in antd(data will be dynmaic)
I have data like below.
Wanted to display as below. Can you please help ?
[{"col1":"temp1","col2":"1","col3":"x"},
{"col1":"temp1","col2":"1","col3":"y"},
{"col1":"temp1","col2":"2","col3":"z"},
{"col1":"temp2","col2":"3","col3":"a"}];
we can write custom render method to resolve this issue.
sample :
render: (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index >= this.state.branch_new_index) {
for (let i = 0; index + i !== metrics.length
&& value === metrics[index + i].branch &&
metrics[index].product === metrics[index + i].product; i += 1) {
obj.props.rowSpan = i + 1;
this.state.branch_count = i + 1;
}
this.state.branch_new_index = index + this.state.branch_count;
if (index + 1 >= metrics.length) {
this.state.branch_new_index = 0;
}
} else {
obj.props.rowSpan = 0;
if (index + 1 >= metrics.length) {
this.state.branch_new_index = 0;
}
}
return obj;
},
I have this array that contains an object which has 4 elements in it:
Task 3: [
{
"action_3": 1,
"action_4": 1,
"action_5": 0,
"action_6": 0
}
]
I have got to this point by doing this:
this.Task3 = this.actions.map(item => {
return {
action_3: item.action_3,
action_4: item.action_4,
action_5: item.action_5,
action_6: item.action_6
}
})
For the next part I would like to check many 1's exist - the result should be 2.
This is my code so far:
task3Progress() {
for (const key of this.Task3) {
const task3length = Object.keys(key).length
//should print 2 to console
console.log(Object.values(key).reduce(
(count, value) => count + (compare === value ? 1 : 0),
0)
);
//prints 4 to screen
return task3length
}
},
I would like to do 2 things:
1) return a count of 4 for the number of elements that exist
2) do a check for how many 1's exits, and return a 2
How do I do this?
Try like this, Hope you will achieve the result.
task3Progress() {
for (var i=0;i<Task3.length;i++){
// will print 4 in console
console.log(Object.keys(Task3[i]).length);
let values= Object.values(Task3[i]);
var equaToOne = values.filter(function (item) {
return item == 1;
})
// will print 2 in console
console.log(equaToOne.length);
return equaToOne.length;
}
}
Below i have attached code snippet too. You can check the result.
var Task3 = [
{
"action_3": 1,
"action_4": 1,
"action_5": 0,
"action_6": 0
}
];
//console.log(Object.keys(Task3[0]).length);
for (var i=0;i<Task3.length;i++){
console.log(Object.keys(Task3[i]).length);
let values= Object.values(Task3[i]);
var equalToOne = values.filter(function (item) {
return item == 1;
})
console.log(equalToOne.length);
}// expected output: 4
check this out.
var task_3 = [
{
"action_3": 1,
"action_4": 1,
"action_5": 0,
"action_6": 0
}
] ;
var key_count = 0 ;
var one_count = 0 ;
var print_keys = function() {
for(action in task_3[0]){
key_count++
if(task_3[0][action] == 1){
one_count++
}
}
console.log('key_count = ',key_count, '& one_count=', one_count)
}
<button onclick="print_keys()">print</button>
This actually has nothing to do specifically with vuejs. It’s only basic javascript:
const actions = [{
"action_3": 1,
"action_4": 1,
"action_5": 0,
"action_6": 0
}];
function countActions() {
return Object.keys(actions[0]).length;
}
function countOccurences(compare) {
return Object.values(actions[0]).reduce(
(count, value) => count + (compare === value ? 1 : 0),
0
);
}
Then call countActions() and countOccurences(1).
I am using a JsonReader to map Json data to variables to be used in a grid/form. The back end is in Java and there are complex objects which I Jsonify and pass to the ExtJS front end.
This is a part of my JsonReader which tries to retrieve a nested object -
{name:'status', type: 'string', mapping: 'status.name'}
This works fine when status has a value (not null in the server), but the grid load fails when status is null. Currently the work around I have is to send an empty object from the server in case of null, but I assume there should be a way to handle this in ExtJS. Please suggest a better solution on the ExtJS side.
I can think of two possibilities - one documented and one undocumented:
use the convert()-mechanism of Ext.data.Field:
{
name:'status',
mapping: 'status',
convert: function(status, data) {
if (!Ext.isEmpty(status) && status.name) {
return status.name;
} else {
return null;
}
}
}
The mapping property can also take an extractor function (this is undocumented so perhaps it may be a little bit risky to rely on this):
{
name:'status',
mapping: function(data) {
if (data.status && data.status.name) {
return data.status.name;
} else {
return null;
}
}
}
Use this safe json reader instead:
Ext.define('Ext.data.reader.SafeJson', {
extend: 'Ext.data.reader.Json',
alias : 'reader.safe',
/**
* #private
* Returns an accessor function for the given property string. Gives support for properties such as the following:
* 'someProperty'
* 'some.property'
* 'some["property"]'
* This is used by buildExtractors to create optimized extractor functions when casting raw data into model instances.
*/
createAccessor: function() {
var re = /[\[\.]/;
return function(expr) {
if (Ext.isEmpty(expr)) {
return Ext.emptyFn;
}
if (Ext.isFunction(expr)) {
return expr;
}
if (this.useSimpleAccessors !== true) {
var i = String(expr).search(re);
if (i >= 0) {
if (i > 0) { // Check all property chain for existence. Return null if any level does not exist.
var a = [];
var l = expr.split('.');
var r = '';
for (var w in l) {
r = r + '.' + l[w];
a.push('obj' + r);
}
var v = "(" + a.join(" && ") + ") ? obj." + expr + " : null";
return Ext.functionFactory('obj', 'return (' + v + ')');
} else {
return Ext.functionFactory('obj', 'return obj' + expr);
}
}
}
return function(obj) {
return obj[expr];
};
};
}()
});
I have changed Slava Nadvorny's example so that it completely works for ExtJS 4.1.1.
New extended class of Ext.data.reader.Json is below:
Ext.define('Ext.data.reader.SafeJson', {
extend: 'Ext.data.reader.Json',
alias : 'reader.safejson',
/**
* #private
* Returns an accessor function for the given property string. Gives support for properties such as the following:
* 'someProperty'
* 'some.property'
* 'some["property"]'
* This is used by buildExtractors to create optimized extractor functions when casting raw data into model instances.
*/
createAccessor: (function() {
var re = /[\[\.]/;
return function(expr) {
if (Ext.isEmpty(expr)) {
return Ext.emptyFn;
}
if (Ext.isFunction(expr)) {
return expr;
}
if (this.useSimpleAccessors !== true) {
var i = String(expr).search(re);
if (i >= 0) {
if (i > 0) { // Check all property chain for existence. Return null if any level does not exist.
var a = [];
var l = expr.split('.');
var r = '';
for (var w in l) {
r = r + '.' + l[w];
a.push('obj' + r);
}
var v = "(" + a.join(" && ") + ") ? obj." + expr + " : null";
return Ext.functionFactory('obj', 'return (' + v + ')');
} else {
return Ext.functionFactory('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
}
}
}
return function(obj) {
return obj[expr];
};
};
}()),
/**
* #private
* #method
* Returns an accessor expression for the passed Field. Gives support for properties such as the following:
*
* - 'someProperty'
* - 'some.property'
* - 'some["property"]'
*
* This is used by buildExtractors to create optimized on extractor function which converts raw data into model instances.
*/
createFieldAccessExpression: (function() {
var re = /[\[\.]/;
return function(field, fieldVarName, dataName) {
var me = this,
hasMap = (field.mapping !== null),
map = hasMap ? field.mapping : field.name,
result,
operatorSearch;
if (typeof map === 'function') {
result = fieldVarName + '.mapping(' + dataName + ', this)';
} else if (this.useSimpleAccessors === true || ((operatorSearch = String(map).search(re)) < 0)) {
if (!hasMap || isNaN(map)) {
// If we don't provide a mapping, we may have a field name that is numeric
map = '"' + map + '"';
}
result = dataName + "[" + map + "]";
} else {
if (operatorSearch > 0) {
var a = [];
var l = map.split('.');
var r = '';
for (var w in l) {
r = r + '.' + l[w];
a.push(dataName + r);
}
result = "("+a.join(" && ")+") ? "+dataName+"."+map+" : null";
} else {
result = dataName + map;
}
}
return result;
};
}())
});
So you can successfully processing nested JSON-data with null nodes.
Example of JSON:
{
root: [{
id: 1,
name: {
name: "John",
phone: "123"
},
},
{
id: 4,
name: null,
},
]
}
Working example with test data you can find here:
http://jsfiddle.net/8Ftag/