reduce formater json to string - javascript

help me solve my problem
I want to bring out this format:
true: 2,3,4
false: 5
i'm use sequelize,
I don't understand how I can correctly output json
see my code below. But it doesn't work. I added
const test = {
one: {
'user': '2',
'status': '1', block: {
'ok': 'false'
}
},
two: {
'user': '3',
'status': '1', block: {
'ok': 'false'
}
},
three: {
'user': '4',
'status': '1', block: {
'ok': 'false'
}
},
five: {
'user': '5',
'status': '0', block: {
'ok': 'true'
}
}
}
const grouped = test.reduce((groups, test) => ({
...groups,
[test.user]: [...(groups[test.user] || []), test.block.ok]
}), {});
const text = Object.entries(grouped).map(([key, values]) => `${key}: ${values}`).join('\n');
console.log(text)

I believe this is what you are trying to accomplish.
true: 5
false: 2,3,4
You cannot reduce the object because it is an Array prototype. You need first to transform your test object into the array with Object.valaues and group them by true and false
const test = {
one: {
user: '2',
status: '1',
block: {
ok: 'false',
},
},
two: {
user: '3',
status: '1',
block: {
ok: 'false',
},
},
three: {
user: '4',
status: '1',
block: {
ok: 'false',
},
},
five: {
user: '5',
status: '0',
block: {
ok: 'true',
},
},
};
const grouped = Object.values(test).reduce(
(groups, group) => {
groups[group.block.ok].push(group.user);
return groups;
},
{ true: [], false: [] },
);
const text = Object.entries(grouped)
.map(([key, values]) => `${key}: ${values}`)
.join('\n');
console.log(text);

Related

Combine 2 arrays based on their common id [duplicate]

This question already has answers here:
Merge two array of objects based on a key
(23 answers)
Closed 4 months ago.
I have 2 different arrays, that i want to combine.
The first one looks like following:
const Cats[] = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
the second one:
const catAges[] = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
and i want to combine them where id from Cats[] and catId from catAges[] are the same and have a result like following:
{ id: '4', age: '13', cat: { id: '1', name: 'Smiley' } },
{ id: '5', age: '4', cat: { id: '2', name: 'Purple' } },
i get the arrays from 2 different async functions looking like this:
const cats = [await getByCatId("1"), await getByCatId("2")];
const catsAge = await getCatsAges();
But i need help in how i combine these 2 and map them. I've tried something like this but without any success:
const all = (cats, catsAge) =>
cats.map(cats=> ({
...catsAge.find((cats) => (catsAge.catId === cats.id) && catsAge),
...cats
}));
console.log(all(cats, catsAge));
Thankful for any help in how to move forward.
const Cats = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
const catAges = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
const transformed = catAges.map(item => {
const cat = Cats.find(cat => cat.id === item.catId);
if (cat) {
item.cat = cat;
delete item.catId;
}
return item;
});
console.log(transformed);
The problem with your function is just that you're re-using the cats variable too much, so in your .find comparision you're comparing an element from catsAge (as cats.id) and the catsAge array (as catsAge.catId) which is undefined.
Try this:
const all = (cats, catsAge) =>
cats.map((cat) => ({
...catsAge.find((catsAge) => catsAge.catId === cat.id),
...cat,
}));
Pro tip: Learn+Use Typescript and the compiler would catch these errors for you :)
const Cats = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
const catAges = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
catAges.map(catage => {
const cat = Cats.find(c => c.id == catage.catId);
if(cat) {
delete catage.catId;
catage.cat = cat;
return catage;
}
});

How to do the sum of the values in an object

//What I'm trying to do is count the sum of the data in this array.
const storage = [
{ data: '1', status: '0' },
{ data: '2', status: '0' },
{ data: '3', status: '0' },
{ data: '4', status: '0' },
{ data: '5', status: '0' },
{ data: '6', status: '0' },
{ data: '7', status: '1' },
];
You can use the reduce here, see more info about reduce
const storage = [{
data: '1',
status: '0'
},
{
data: '2',
status: '0'
},
{
data: '3',
status: '0'
},
{
data: '4',
status: '0'
},
{
data: '5',
status: '0'
},
{
data: '6',
status: '0'
},
{
data: '7',
status: '1'
},
];
const sum = storage.reduce((acc, value) => acc + Number(value.data), 0);
console.log(sum)
Just use a simple loop - no need to get snarled up with reduce.
(Just make sure you coerce the string value to a Number when you're doing the addition.)
const storage=[{data:"1",status:"0"},{data:"2",status:"0"},{data:"3",status:"0"},{data:"4",status:"0"},{data:"5",status:"0"},{data:"6",status:"0"},{data:"7",status:"1"}];
let sum = 0;
for (const obj of storage) {
sum += Number(obj.data);
}
console.log(sum);
Something like this?
const total = storage.map(({data}) => Number(data)).reduce((a,b) => a + b, 0)
So, first, lets get an array of numbers, which is de first part:
storage.map(({data}) => Number(data))
This will get the data by destructuring from each of the elements, or you can write it like so:
storage.map((item) => Number(item.data))
Then we'll reduce the list by adding all the items together:
list.reduce((a,b) => a + b, 0)
This means, start with 0, then foreach element, add it to the result. This will give you the total.

JS merge two subarray using map

I use the following to merge two arrays:
var mySeries = [
{ name: '4', data: [4] },
{ name: '3', data: [3] }
];
var mySeries1 = [
{ name: '5', data: [0] },
{name: '4', data:[0]},
{name: '3', data:[0]},
{name: '2', data:[0]},
{ name: '1', data: [0] }
];
var res = mySeries1.map(obj => mySeries.find(o => o.name === obj.name) || obj);
console.log(res);
Works great; however, my challenge is my array is structured as:
var myArray = [{
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }]
}];
];
So I need to map subarrays, tried using the following:
var res = myArray.mySeries1.map(obj => myArray.mySeries.find(o => o.name === obj.name) || obj);
I get this error:
Cannot read properties of undefined (reading 'map')
How can I point to the subarray?
var myArray = [{
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }
]
}];
var res = myArray[0].mySeries1.map(obj => myArray[0].mySeries.find(o => o.name === obj.name) || obj);
console.log(res)
you could change your array to dictionary and iterate it like you already did.
var myArray = {
mySeries : [
{ name: '4', data: [4] },
{ name: '3', data: [3] }],
mySeries1 : [
{ name: '5', data: [0] },
{ name: '4', data: [0] },
{ name: '3', data: [0] },
{ name: '2', data: [0] },
{ name: '1', data: [0] }]
};
i.e. var res = myArray.mySeries1.map(obj => myArray.mySeries.find(o => o.name === obj.name) || obj);

How to loop through array of objects and make key value pairs?

I have an array of objects like this:
let someObj = {
items: [{
id: '12',
value: true
}, {
id: '34',
value: true
}, {
id: '56',
value: false
}]
}
I want add this to an exiting object, where id is a key of this object, like this:
let obj = {
someKey: someValue,
'12': true,
'34': true,
'56': false,
}
You may achieve your goal using Array#reduce as follows:
const input = {
items: [{
id: '12',
value: true
}, {
id: '34',
value: true
}, {
id: '56',
value: false
}]
}
const output = input.items.reduce((o, {
id,
value
}) => (o[id] = value, o), {})
console.log(output)
Also, and maybe the simplest approach might be using Array#map to turn objects into pairs and then convert them into an object using Object.fromPairs:
const input = {
items: [{
id: '12',
value: true
}, {
id: '34',
value: true
}, {
id: '56',
value: false
}]
}
const output = Object.fromEntries(input.items.map(({
id,
value
}) => [id, value]))
console.log(output)
Finally, here's a functional approach:
// Composes two functions
const compose = f => g => x => f (g (x))
// Given the key-value pairs of some object with 2 properties, maps a pair of values
const values = ([[, x], [, y]]) => [x, y]
// Turns an object of two properties into a pair of property values
const entry = compose (values) (Object.entries)
// Turns many objects of two properties, into an object on which
// keys are first properties' values, and vaules the second properties' values.
const keyValueObject = xs => Object.fromEntries (xs.map (entry))
const input = {
items: [{
id: '12',
value: true
}, {
id: '34',
value: true
}, {
id: '56',
value: false
}]
}
const output = keyValueObject (input.items)
console.log(output)
You can iterate each item from items and create a new object as shown below.
let someObj = {
items: [{
id: '12',
value: true
}, {
id: '34',
value: true
}, {
id: '56',
value: false
}]
}
const newObj = {};
someObj.items.map(item =>{
newObj[item.id]= item.value;
});
console.log(newObj);
Use map and Object.values will simplify.
const output = arr => Object.fromEntries(arr.map(Object.values));
let someObj = {
items: [
{
id: "12",
value: true,
},
{
id: "34",
value: true,
},
{
id: "56",
value: false,
},
],
};
console.log(output(someObj.items));
First, you can transform the itens into "KV" entries
> someObj.items.map(({id, value}) => [id, value])
[ [ '12', true ], [ '34', true ], [ '56', false ] ]
Then turn it into Object
> Object.fromEntries(someObj.items.map(({id, value}) => [id, value]))
{ '12': true, '34': true, '56': false }
You can do a function
> let ObjectFromMapping = (vs, mapping) => Object.fromEntries(vs.map(mapping))
> ObjectFromMapping(someObj.items, ({id, value}) => [id, value])
{ '12': true, '34': true, '56': false }
Maybe turn vs into a iterable is a good idea
> let ObjectFromMapping = (vs, mapping) => Object.fromEntries([... vs].map(mapping))
> ObjectFromMapping("abc", (char, idx) => [idx, char])
{ '0': 'a', '1': 'b', '2': 'c' }
Then your function will work on any iterable

Javascript filter method, Remove all Items with matching values in array

I'm trying to remove all items if they match with array values but it's removing only one item. How can i remove all items with filter method or what is the best way to achieve this.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
data = data.filter(post => {
let remove = ['2', '4', '5']
for(let i = 0; i < remove.length; i++) {
return post.id !== remove[i]
}
})
console.log(data)
Thanks
you should return false if you want to remove item from array
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id);
})
console.log(data)
All the notice are in the snippet's comment
let data = [ { id: '1', title: 'ABC' }, { id: '2', title: 'DEF' }, { id: '3', title: 'GHI' }, { id: '4', title: 'JKL' }, { id: '5', title: 'MNO' } ]
const remove = ['2', '4', '5']
// `indexOf` is from ES5
data = data.filter(post => remove.indexOf(post.id) === -1)
console.log(data)
// `includes` is from ES7
data = data.filter(post => !remove.includes(post.id))
console.log(data)
// this will recreate the array ['2', '4', '5'] 5 times
data = data.filter(post => !['2', '4', '5'].includes(post.id))
console.log(data)
There is no need to use for loop inside of filter.
Instead it is possible to use some method inside of filter. The some method checks whether at least one element satisfies condition inside of provided function. So unnecessary iteration will be avoided:
data.filter(f => !remove.some(s => s == f.id))
An example:
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
console.log(data.filter(f => !remove.some(s => s == f.id)));
I'll suggest using includes rather then a nested for loop.
You should also move the remove var outside of the loop, so it's not reinitialised every time.
The callback to the filter method is a predicate. If the condition evaluates to true, the current value in the iteration will be returned. In your case, you want to return if the current value is not in the remove array.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
const remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id)
})
console.log(data)

Categories