Filter Map and Reduce - javascript

I have the following line of code:
$scope.listDeColaboradoresObject.forEach(item => {
item.listNmAssunto = $scope.relatorioTotalMensagensRespondidasColab
.filter(x => x.nmUsuario == item.nmUsuario)
.map(x => x.nmAssunto);
item.listNmAssunto = $scope.removeDuplicates(item.listNmAssunto);
item.listDtResposta = $scope.relatorioTotalMensagensRespondidasColab
.filter(x => x.nmUsuario == item.nmUsuario)
.map(x => x.dtResposta);
});
that runs through this array:
0: {deTipoAtendimento: "012", nmAssunto: "Cartão extraviado", nmUsuario: "15", dtResposta: "2018", total: 1}
1: {deTipoAtendimento: "012", nmAssunto: "Assunto Novo 012", nmUsuario: "Admin", dtResposta: "2018", total: 2}
2: {deTipoAtendimento: "012", nmAssunto: "Assunto Novo 012", nmUsuario: "Administrador", dtResposta: "2018", total: 1}
3: {deTipoAtendimento: "012", nmAssunto: "Assunto Novo 012", nmUsuario: "Administrador IMB", dtResposta: "2018", total: 3}
4: {deTipoAtendimento: "012", nmAssunto: "Assunto Teste GREAt", nmUsuario: "Administrador IMB", dtResposta: "2018", total: 2}
5: {deTipoAtendimento: "012", nmAssunto: "Thais 23042018", nmUsuario: "Administrador IMB", dtResposta: "2018", total: 2}
6: {deTipoAtendimento: "012", nmAssunto: "teste Alterado2", nmUsuario: "Administrador IMB", dtResposta: "2018", total: 1}
and that returns me the following array:
0: {nmUsuario: "15", listNmAssunto: Array(1), listDtResposta: Array(1), $$hashKey: "object:2975"}
1: {nmUsuario: "Admin", listNmAssunto: Array(1), listDtResposta: Array(1), $$hashKey: "object:2976"}
2: {nmUsuario: "Administrador", listNmAssunto: Array(1), listDtResposta: Array(1), $$hashKey: "object:2977"}
3: {nmUsuario: "Administrador IMB", listNmAssunto: Array(4), listDtResposta: Array(4), $$hashKey: "object:2978"}
My question is how do I at the time of the map insert both the nmSubject and the dtResponse within the same array

Why you don’t map into one object?
Like this:
$scope.listDeColaboradoresObject.forEach(item => {
item.listAssunto = $scope.relatorioTotalMensagensRespondidasColab
.filter(x => x.nmUsuario == item.nmUsuario)
.map(x => {a:x.nmAssunto,b: x.dtResposta});
item.listNmAssunto = $scope.removeDuplicates(item.listAssunto);
});

The code you've will just update the existing array. I'm not sure how it creates the output you've posted. But, looking at your output, I'm assuming you want to group based on the nmUsuario and create an array of objects with 2 array properties. You can do the following using reduce, destructiring and Object.values
const input = [{deTipoAtendimento:"012",nmAssunto:"Cartão extraviado",nmUsuario:"15",dtResposta:"2018",total:1},{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Admin",dtResposta:"2018",total:2},{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Administrador",dtResposta:"2018",total:1},{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Administrador IMB",dtResposta:"2018",total:3},{deTipoAtendimento:"012",nmAssunto:"Assunto Teste GREAt",nmUsuario:"Administrador IMB",dtResposta:"2018",total:2},{deTipoAtendimento:"012",nmAssunto:"Thais 23042018",nmUsuario:"Administrador IMB",dtResposta:"2018",total:2},{deTipoAtendimento:"012",nmAssunto:"teste Alterado2",nmUsuario:"Administrador IMB",dtResposta:"2018",total:1}]
const merged = input.reduce((r,{ nmUsuario, nmAssunto, dtResposta }) => {
r[nmUsuario] = r[nmUsuario] || {nmUsuario, listNmAssunto: [], listDtResposta:[]};
r[nmUsuario].listNmAssunto.push(nmAssunto);
r[nmUsuario].listDtResposta.push(dtResposta);
return r;
},{})
const output = Object.values(merged);
console.log(output)

As per your results comment, it looks like you want to group your list by nmUsuario, but create a single array of objects that hold the relevant nmAssunto and dtResposta. You can achieve this with reduce(). Basically, you create an object with an empty array for each nmAssunto, and push a new object into the correct array each iteration. Then use Object.values() to convert to the final output array.
const data = [
{deTipoAtendimento:"012",nmAssunto:"Cartão extraviado",nmUsuario:"15",dtResposta:"2018",total:1},
{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Admin",dtResposta:"2018",total:2},
{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Administrador",dtResposta:"2018",total:1},{deTipoAtendimento:"012",nmAssunto:"Assunto Novo 012",nmUsuario:"Administrador IMB",dtResposta:"2018",total:3},
{deTipoAtendimento:"012",nmAssunto:"Assunto Teste GREAt",nmUsuario:"Administrador IMB",dtResposta:"2018",total:2},
{deTipoAtendimento:"012",nmAssunto:"Thais 23042018",nmUsuario:"Administrador IMB",dtResposta:"2018",total:2},
{deTipoAtendimento:"012",nmAssunto:"teste Alterado2",nmUsuario:"Administrador IMB",dtResposta:"2018",total:1}
]
const groups = data.reduce((r, { nmUsuario, nmAssunto, dtResposta }) => {
r[nmUsuario] = r[nmUsuario] || {
nmUsuario,
listAssunto: []
}
r[nmUsuario].listAssunto.push({
a: nmAssunto,
b: dtResposta
})
return r
}, {})
console.log(Object.values(groups))

Related

push the total amount of objects to an array

I am trying to count how many times a specific item appears in an array. And then push that amount to an other array. I got the counter working, although when I push this amount to the array the type of this value turn out te be Not A Number...
Here is my code:
res2 =
0: (2) [29682885, "Jean-Paul"]
1: (2) [29682886, "DEMO Martin"]
2: (2) [29682887, "Johan"]
3: (2) [29682892, "Peter"]
4: (2) [29682900, "Antoine"]
5: (2) [29682902, "Sandra"]
6: (2) [29682906, "Kevin"]
7: (2) [29682910, "Wouter"]
8: (2) [29682911, "Tom"]
9: (2) [4, "Autotask"]
res3 =
0: (2) [29682885, "2019-05-16T08:25:32Z"]
1: (2) [29682885, "2019-07-01T13:11:00Z"]
2: (2) [29682885, "2019-07-03T10:21:07Z"]
3: (2) [29682885, "2019-09-03T14:00:45Z"]
4: (2) [29682885, "2019-09-11T09:59:07Z"]
5: (2) [29682885, "2019-09-17T14:13:39Z"]
6: (2) [29682885, "2019-10-09T16:48:41Z"]
7: (2) [29682885, "2019-10-30T13:48:12Z"]
8: (2) [29682885, "2019-10-30T14:13:01Z"]
9: (2) [29682885, "2019-10-30T14:34:13Z"]
10: (2) [29682885, "2019-11-07T13:41:27Z"]
11: (2) [29682885, "2019-11-22T12:41:08Z"]
...
res2.sort();
res3.sort();
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
console.log(person[1]);
} else {
person[1].occurrences++;
console.log(person[1]);
prepArray.push(person[1]);
}
prepArray.push(person[1]);
}
});
});
prepArray.push(person[1]); retruns an NaN somehow. But the console shows the exact amount I would like to push to my prepArray...
I've used a mix of filter, flat, map to achieve this. Added code comments to explain what logic is being used.
res2 = [[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"]]
res3 = [[29682885, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682885, "2019-09-17T14:13:39Z"],
[29682902, "2019-10-09T16:48:41Z"],
[4, "2019-10-30T13:48:12Z"],
[4, "2019-10-30T14:13:01Z"],
[29682911, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]];
// pick only the ids from res3
// this makes it easier for comparison
let res = res3.map(v => {
return v.shift();
}).flat()
let final = [];
// loop over res2, and count occurrences using .filter().length
res2.map(sale => final.push([sale[1], res.filter(person => person === sale[0]).length]));
console.log(final);
// if you want the output as an object,
// you can do the following
let finalObj = {};
res2.map(sale => finalObj[sale[1]] = res.filter(person => person === sale[0]).length);
console.log({ finalObj })
I've modified the input set (res3) slightly to show the difference in counts, the above code outputs the following,
[
[
"Jean-Paul",
5
],
[
"DEMO Martin",
0
],
[
"Johan",
0
],
[
"Peter",
0
],
[
"Antoine",
0
],
[
"Sandra",
2
],
[
"Kevin",
0
],
[
"Wouter",
0
],
[
"Tom",
3
],
[
"Autotask",
2
]
]
Edited my answer to get the desired output in object format, so now you'll get,
{
"Jean-Paul": 5,
"DEMO Martin": 0,
"Johan": 0,
"Peter": 0,
"Antoine": 0,
"Sandra": 2,
"Kevin": 0,
"Wouter": 0,
"Tom": 3,
"Autotask": 2
}
I don't understand many parts of your code, but trying to interpretate it:
res2 = [
[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"],
];
res3 = [
[29682911, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682902, "2019-09-17T14:13:39Z"],
[29682885, "2019-10-09T16:48:41Z"],
[29682885, "2019-10-30T13:48:12Z"],
[29682885, "2019-10-30T14:13:01Z"],
[29682885, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]
]
res2.sort();
res3.sort();
const prepArray = {};
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
}
prepArray[person[1]] = prepArray[person[1]] || 0;
prepArray[person[1]] += 1;
}
});
});
console.log(prepArray)

How to merge nested arrays into a new object?

I am struggeling a bit to merge nested arrays into a new object.
I have an array with nested objects in it. The objects contain an array. Now I want to merge the entries of this array into a new object and assign a value to it. For example "false". Please see the example.
Current Structure:
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: [
"4",
"5",
"6",
"7",
],
},
]
Target Structure: merge "foo" entries into object and assign value.
const obj = {
1: false,
2: false,
3: false,
4: false,
5: false,
6: false,
7: false,
};
Fetch the array foo and iterate over using forEach and get the value and make it a property, You can do this using reduce.
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: ["4", "5", "6", "7"],
},
];
const result = arr.reduce((acc, curr) => {
const { foo } = curr;
foo.forEach((el) => (acc[el] = false));
return acc;
}, {});
console.log(result);
More declarative answer:
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: ["4", "5", "6", "7"],
},
];
// Build `obj` from `arr`
const obj = Object.fromEntries(
arr.map(val => val.foo)
.flat()
.map(
key => [key, false]
)
)
console.log(obj)
Side note: not compatible with legacy browsers such as IE11, see coverage here: https://caniuse.com/mdn-javascript_builtins_object_fromentries
While the other answers are correct I find them so much harder to read than a simple double loop.
let result = {}
for(let obj of arr){
for(let innerArrElem of obj.foo){
result[innerArrElem] = false
}}
}}
function populate(arr, value) {
return arr.reduce((acc, element) => {
element.foo.forEach((f) => acc[f] = false);
return acc;
}, {})
}

How can I convert an indexed JavaScript object to an array of objects?

I have an object that looks like this:
obj = {
"price": {0: "10.00", 1: "15.00", 2: "6.00"},
"serialNumber": {0: 1000, 1: 2000, 2: 3000}
}
I'm trying to convert it into an array of objects so I can do obj.map((obj, idx)=>{//display obj.price and obj.serialNumber//}), so I want to convert obj into an array like this:
obj_array = [{"price":"10.00", "serialNumber": 1000}, {"price":"15.00", "serialNumber": 2000},{"price":"6.00", "serialNumber": 3000}]
I initially used array = Object.values(obj['serialNumber']) to just get serialNumber, but due to the way Object.values works, I can't just do array = Object.values(obj['serialNumber','price']) to get both. The values() function will ignore the serialNumber field and just make an array of prices. Any help would be appreciated!
You can use array#reduce with Object.entries() to convert your object to array.
const obj = { "price": { 0: "10.00", 1: "15.00", 2: "6.00" }, "serialNumber": { 0: 1000, 1: 2000, 2: 3000 } },
result = Object.entries(obj).reduce((r,[key, value]) => {
Object.values(value).forEach((val, i) => {
r[i] = {...(r[i] || {}), [key]: val};
});
return r;
},[]);
console.log(result);

riot js pushing index to a array

I woking in riot js and i have sorted the following abclist as following.
abclist = [];
abc = {year:year, name1:name1, order:order};
abclist.push(abc);
abclist.sort(function(a,b) {return (a.order > b.order) ? 1 : ((b.order > a.order) ? -1 : 0);} );
printing on console the abclist is like below.
0: {year: "2018", name1: "cc", order: "1"}
1: {year: "2018", name1: "jj", order: "2"}
I want to add these array index(0,1)to the array like below.
0: {index:0, year: "2018", name1: "cc", order: "1"}
1: {index:1, year: "2018", name1: "jj", order: "2"}
Please help me on this.
The question is not strictly related to riot.
An easy way to achieve that is to reiterate the array and add a field to each object like this:
for(var i = 0; i < abclist.length; i++){
abclist[i]['index'] = i;
}
You can see it in this fiddle: https://jsfiddle.net/7esmssup/6/

how to transform object with list of properties to array when Array.prototype.slice.call does not work?

This is working for list:
> Array.prototype.slice.call([1,2,3])
> [1, 2, 3]
How to create list from this type of data {1: "1", 2: "2", 3: "3"} ? Are there other methods than iterating object with for ?
the Array.prototype.slice.call() is not working here and gives []
This came from data = Object {0: Object, 1: Object, 2: Object, total : '29'} and then i delete data['total'] and need to access to slice, pop and other methods of Array
You could use the keys and map the values.
var o = {1: "1", 2: "2", 3: "3"},
a = Object.keys(o).map(function (k) {
return o[k];
});
console.log(a);
console.log(Array.prototype.slice.call({1: "1", 2: "2", 3: "3", length:5}));
The question arised, why Array.prototype.slice.call does not work. Basically because a length property is missing.
Only properties, which can be used as indices are used.
var o1 = {1: "1", 2: "2", 3: "3"},
o2 = {1: "1", 2: "2", 3: "3", length: 5},
o3 = {1: "1", 2: "2", 3: "3", abc: 42, length: 5},
o4 = {0: "0", 1: "1", 2: "2", 3: "3"};
o4.length=Object.keys(o4).length;
console.log(Array.prototype.slice.call(o1));
console.log(Array.prototype.slice.call(o2));
console.log(Array.prototype.slice.call(o3));
console.log(Array.prototype.slice.call(o4));
Note: Dynamic length of properties-in-object could be assigned using Object.keys(OBJECT). The cause of getting undefined in console is missing property at index 0
var list = [];
for (item in obj) {
list.push(obj[item]);
}
//use list.push(parseInt(obj[item])) for number array
You can also do the following if you want it straight
Object.values(obj);

Categories

Resources