I understand that for count an array in Angular with rxjs I use reduce, for example if I want count : [{id: 1, items: [10, 20, 30]}] I use the following code:
const item = from([{id: 1, items: [10, 20, 30]}]);
item.pipe(
map(actions => actions.items),
mergeAll(),
reduce((acc, i) => acc + i, 0)
).subscribe(p => console.log('Print 60: ', p));
The questions is How get make a reducer in the following array:
const items = [
{
id: 1,
boxing: [1, 2, 2]
},
{
id: 2,
boxing: [10, 10, 20]
}];
result expected:
[{
id: 1,
boxing: 5
},
{
id: 2,
boxing: 40
}]
I will appreciate your help
You can easily do this with javascript by using reduce and map as
const items = [
{id: 1, boxing: [1, 2, 2]},
{id: 2, boxing: [10, 10, 20]}
];
let reducedItems = items.map(val => {
return {
id: val.id,
boxing: val.boxing.reduce((a, i) => a + i)
}
});
console.log(reducedItems);
One approach can be this.
from(items).pipe(
mergeMap((data) => from(data['boxing']).pipe(
reduce((acc, x) => acc + x),
map((val) => { data['boxing'] = val; return data })
)),
toArray()
).subscribe((val) => console.log(val));
Related
How to verify with i have only 2 or 3 numbers inside this?
without this ----> if(Array.includes(1) && !Array.includes(3))
const servicesTest: IServices[] = [
{
id: '1',
name: 'Hair',
price: 25,
icon: 'https://cdn-icons-png.flaticon.com/512/7478/7478480.png'
},
{
id: '2',
name: 'Beard',
price: 20,
icon: 'https://cdn-icons-png.flaticon.com/512/7578/7578754.png'
},
{
id: '3',
name: 'Eyebrow',
price: 15,
icon: 'https://cdn-icons-png.flaticon.com/512/2821/2821012.png'
}
]
if the client choose hair + beard this will be 40 not 45.
I´m doing this:
const name = findServices.map(services => services.name)
if (name.includes('Hair') && name.includes('Beard') && !name.includes('Eyebrown')) {
return (
setTotalDay(prevState => prevState + 40),
setTotalMonth(prevState => prevState + 40)
)
}
I would create an array of discounts like this:
const discounts = [{
price: 30,
ids: [1, 2],
}];
Then check if the array has only discounted items like this:
array.length === discount.ids.length && array.every((item) => discount.ids.includes(item.id))
const discounts = [{
price: 30,
ids: [1, 2],
}];
const discounted = [{
id: 1,
name: 'Hair',
price: 20,
},
{
id: 2,
name: 'Beard',
price: 30,
},
];
const fullPrice = [{
id: 1,
name: 'Hair',
price: 20,
},
{
id: 2,
name: 'Beard',
price: 30,
},
{
id: 3,
name: 'Tea',
price: 30,
},
];
console.log("discounted", getTotal(discounted));
console.log("full price", getTotal(fullPrice));
function getTotal(array) {
for (const discount of discounts) {
if (
array.length === discount.ids.length &&
array.every((item) => discount.ids.includes(item.id))
) {
return discount.price;
}
}
return array.reduce((sum, item) => sum + item.price, 0);
}
answering your question before the edit.
Assuming we have this array
const Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Let's say we want to check if values 2 and 3 exist.
We store the values in an array let toCheck = [2,3];
We can use function every to loop all the elements of toCheck array against the Array const
Example Follows:
const Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let toCheck = [1,2];
const allExist = toCheck.every(value => {
return Array.includes(value);
});
Hope it helps.
How do I solve this while using include()?
const allowedIds = [1, 3]
const allBoats = [{
id: 1,
name: 'titanic'
}, {
id: 2,
name: 'anna'
}, {
id: 3,
name: 'boaty McBoatface'
}, ]
const expectedResult = ['boaty McBoatface', 'titanic']
Consider making allowedIds a Set and then using has, which is O(1), rather than includes on an Array, which is O(N):
const allowedIds = new Set([1, 3]);
const allBoats = [
{
id: 1,
name: "titanic",
},
{
id: 2,
name: "anna",
},
{
id: 3,
name: "boaty McBoatface",
},
];
const allowedBoats = allBoats.filter(b => allowedIds.has(b.id))
.map(b => b.name)
.sort();
console.log(allowedBoats);
Other potentially useful documentation links:
Array.prototype.filter()
Array.prototype.map()
Array.prototype.sort()
const allowedIds = [1, 3]
const allBoats = [{
id: 1,
name: 'titanic'
}, {
id: 2,
name: 'anna'
}, {
id: 3,
name: 'boaty McBoatface'
}, ]
const result = allBoats
.filter(b => allowedIds.includes(b.id))
.map(b => b.name)
.sort((a, b) => a.localeCompare(b))
console.log('result', result)
You can try this as well
allBoats.filter(entry => allowedIds.includes(entry.id)).map(item => item.name).sort()
const allowedIds = [1, 3]
const allBoats = [
{
id: 1,
name: 'titanic'
},
{
id: 2,
name: 'anna'
},
{
id: 3,
name: 'boaty McBoatface'
}
]
const expectedResult = allBoats.reduce((p, c) => allowedIds.includes(c.id) ? p.concat(c.name) : p, []).sort((a, b) => a.localeCompare(b));
console.log(expectedResult);
if you want only those with id 1 or 3:
const selections = allBoats.filter((val)=>{return val.id === 1 || val.id ===3});
const result = selections.map((val,key)=>{ val.name}).sort()
console.log(result) //gives ["boaty McBoatface", "titanic"]
i want to sort an array of objects having id each object using another array that only has the ids, for example:
object = [
{id: 2, name: carlos},
{id: 1, name: maria},
{id: 4, name: juan},
{id: 3, name: pepe}, //this is the array that i want to be sorted or create a copy to return it
]
[1,2,3,4,5] //this is the array that i will use as reference to sort the first one
the final result should be:
object = [
{id: 1, name: maria},
{id: 2, name: carlos},
{id: 3, name: pepe},
{id: 4, name: juam}, //this is the array that i want to be sorted or create a copy to return it
]
im using two maps, but im always getting and array with undefined:
array_to_be_sorted.map((objects) => {
array_reference.map((id) => {
if (objects.id === id) {
return {...objects}
}
}
}
im using map cause think is the best way for bigs array, because im building a music player, so dont know how many tracks the does the user has
You could use Array.prototype.sort() method to get the result.
const data = [
{ id: 2, name: 'carlos' },
{ id: 1, name: 'maria' },
{ id: 4, name: 'juan' },
{ id: 3, name: 'pepe' },
];
const order = [1, 2, 3, 4, 5];
data.sort((x, y) => order.indexOf(x.id) - order.indexOf(y.id));
console.log(data);
Another solution using Map Object which is faster than the first one.
const data = [
{ id: 2, name: 'carlos' },
{ id: 1, name: 'maria' },
{ id: 4, name: 'juan' },
{ id: 3, name: 'pepe' },
];
const order = [1, 2, 3, 4, 5];
const map = new Map();
order.forEach((x, i) => map.set(x, i));
data.sort((x, y) => map.get(x.id) - map.get(y.id));
console.log(data);
Why not just use Array.prototpye.sort()? It's easy and fast.
const pre = document.querySelector('pre');
let object = [
{id: 2, name: 'carlos'},
{id: 1, name: 'maria'},
{id: 4, name: 'juan'},
{id: 3, name: 'pepe'}
];
const criteria = [1,2,3,4,5];
pre.innerText = 'object:' + JSON.stringify(object, null, 2) + '\n\n';
object.sort((a, b) => {
return criteria[a.id] - criteria[b.id];
});
pre.innerText += 'sorted object:' + JSON.stringify(object, null, 2);
Sort an array using criteria from a second array:
<pre></pre>
You can take advantage of Schwartzian transform and sort data based on another array.
const data = [ { id: 2, name: 'carlos' }, { id: 1, name: 'maria' }, { id: 4, name: 'juan' }, { id: 3, name: 'pepe' }, ],
order = [4, 2, 3, 1, 5],
result = data.map(o => {
const index = order.indexOf(o.id);
return [index, o];
})
.sort((a, b) => a[0] - b[0])
.map(([, o]) => o);
console.log(result);
Let's say, I have an Array of object which looks like:
var jsonData = [
{"DS01":123,"DS02":88888,"DS03":1,"DS04":2,"DS05":3,"DS06":666},
{"DS01":123,"DS02":88888,"DS03":2,"DS04":3,"DS05":4,"DS06":666},
{"DS01":124,"DS02":99999,"DS03":3,"DS04":4,"DS05":5,"DS06":333},
{"DS01":124,"DS02":99999,"DS03":5,"DS04":6,"DS05":7,"DS06":333}
];
You can see there are some common key fields which are DS01, DS02 and DS06. Firstly, I want to find which are common group of keys.
For first 2 Objects : DS01 = 123, DS02 = 88888, DS06 = 666
For last 2 Objects : DS01 = 124, DS02 = 99999, DS06 = 333
I want to convert this array of objects to a format like this:
var jsonDataReduced =
[{
"DS01": 123,
"DS02": 88888,
"DS03": [1, 2],
"DS04": [2, 3],
"DS05": [3, 4],
"DS06": 666
},
{
"DS01": 124,
"DS02": 99999,
"DS03": [3, 5],
"DS04": [4, 6],
"DS05": [5, 7],
"DS06": 333
}
];
Let's say, I have another array of objects.
var jsonData2 = [{
"Mass": 3,
"Force": 3.1,
"Acceleration": 4
}, {
"Mass": 3,
"Force": 4.1,
"Acceleration": 4
}];
So after reducing it should be:
var jsonData2 = [{
"Mass": 3,
"Force": [3.1, 4.1],
"Acceleration": 4
}];
I have been trying to do these by using Array.reduce() but not getting an idea on how to do this job efficiently.
Is it possible to
making a single function
passing these kinds of array of objects as a parameter
and finally getting the reduced dataset
What I have tried :
var jsonData2 = [{
"Mass": 3,
"Force": 3.1,
"Acceleration": 4
}, {
"Mass": 3,
"Force": 4.1,
"Acceleration": 4
}];
const reduced = jsonData2.reduce((r, e, i, a) => {
if (i % 2 == 0) {
const next = a[i + 1];
const obj = { ...e, Force: [e.Force] }
if (next) obj.Force.push(next.Force);
r.push(obj)
}
return r;
}, []);
console.log(reduced);
You could get common keys and group by them.
var data = [{ DS01: 123, DS02: 88888, DS03: 1, DS04: 2, DS05: 3, DS06: 666 }, { DS01: 123, DS02: 88888, DS03: 2, DS04: 3, DS05: 4, DS06: 666 }, { DS01: 124, DS02: 99999, DS03: 3, DS04: 4, DS05: 5, DS06: 333 }, { DS01: 124, DS02: 99999, DS03: 5, DS04: 6, DS05: 7, DS06: 333 }],
common,
temp = data.reduce((r, o, i) => {
Object.entries(o).forEach(([k, v]) => {
r[k] = r[k] || [];
r[k][i] = v;
});
return r;
}, {}),
min = Infinity,
result;
Object.entries(temp).forEach(([k, a]) => {
var s = new Set;
temp[k] = a.map(v => s.add(v).size);
min = Math.min(min, s.size);
});
common = Object.keys(temp).filter(k => temp[k][temp[k].length - 1] === min);
result = data.reduce((r, o) => {
var temp = r.find(q => common.every(k => q[k] === o[k]));
if (!temp) {
r.push({ ...o });
} else {
Object.keys(o).filter(k => !common.includes(k)).forEach(k => Array.isArray(temp[k]) ? temp[k].push(o[k]) : (temp[k] = [temp[k], o[k]]));
}
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have an array looks like below...
arr = [{
Bildbearbeiter: 1,
Bügler: 2,
Einkäufer: 3,
Empfänger: 4,
Fotograf: 5,
}];
but I want to change it
arr = [{
Bildbearbeiter: 1
},
{
Bügler: 2
},
{
Einkäufer: 3
},
{
Empfänger: 4
},
{
Fotograf: 5
}
];
So that i can iterate with each object. Is there any way to solve it??
Thanks in advance
Use Array.map and Object.entries
let arr = [{Bildbearbeiter: 1,Bügler: 2,Einkäufer: 3,Empfänger: 4,Fotograf: 5}];
arr = Object.entries(arr[0]).map(([k,v]) => ({[k]:v}));
console.log(arr);
You can simply use Array.map() and Object.keys():
let arr = [ { Bildbearbeiter: 1, Bügler: 2, Einkäufer: 3, Empfänger: 4, Fotograf: 5, } ];
let result = Object.keys(arr[0]).map((key)=> ({[key] : arr[0][key]}));
console.log(result);
Try this by clicking on Run code snippet button:
var arr = [{
Bildbearbeiter: 1,
Bügler: 2,
Einkäufer: 3,
Empfänger: 4,
Fotograf: 5,
}];
var newArray = [];
for (let key in arr[0]) {
newArray.push({
[key]: arr[0][key]
});
}
console.log(newArray);
Or try this:
var arr = [{
Bildbearbeiter: 1,
Bügler: 2,
Einkäufer: 3,
Empfänger: 4,
Fotograf: 5,
}];
var newArray = Object.keys(arr[0]).map(key => ({
[key]: arr[0][key]
}))
console.log(newArray);
You could reduce the array by adding all objects to the result set.
var array = [{ "Bildbearbeiter": 1, "Bügler": 2, "Einkäufer": 3, "Empfänger": 4, "Fotograf": 5 }],
result = array.reduce((r, o) => r.concat(Object.entries(o).map(([k, v]) => ({ [k]: v }))), []);
console.log(result);
You can map the array, loop through the keys of each object, and assign a brand new object holding the key and the value of the current item.
arr.map(i => {
return Object.keys(i).map(k => {
return {[k]: i[k]};
});
});
Working fiddle: http://jsfiddle.net/sw3Lxm7f/