Hello I am new to the site, and I have a problem with javascript that I do not know how to fix.
I have an array, which I want to turn into an object.
arr = [
{prefer: "sport_swimming", rating: "1"},
{prefer: "sport_running", rating: "5"},
{prefer: "sport_tennis", rating: "2"},
{prefer: "study_archeology", rating: "4"}];
obj = Object.assign({}, arr);
console.log(obj);
I want to get to something like this:
{
"sport": {
"swimming":"1",
"running":"5",
"tennis":"2"
},
"study":
{
"archeology":"4"
}
}
Using reduce you can look over the array and build an object using the keys you split off the property.
const arr = [
{prefer: "sport_swimming", rating: "1"},
{prefer: "sport_running", rating: "5"},
{prefer: "sport_tennis", rating: "2"},
{prefer: "study_archeology", rating: "4"}
];
const out = arr.reduce((acc, data) => {
const parts = data.prefer.split("_");
acc[parts[0]] = acc[parts[0]] || {};
acc[parts[0]][parts[1]] = data.rating;
return acc;
}, {});
console.log(out);
You can use reduce:
const arr = [
{ prefer: "sport_swimming", rating: "1" },
{ prefer: "sport_running", rating: "5" },
{ prefer: "sport_tennis", rating: "2" },
{ prefer: "study_archeology", rating: "4" }];
const result = arr.reduce((a, e) =>
([parent, child] = e.prefer.split('_'),
(a[parent] ??= {})[child] = e.rating,
a), {});
console.log(result);
Related
I would like to transform values inside an object of an object. Something like this:
Initial object:
const studentDetails = {
'details1': {Name: "John", CountryName: "US", value: 1},
'details2': {Name: "David", CountryName: "AUS", value: 2},
'details3': {Name: "Bob", CountryName: "UK", value: 3},
};
Transformed object:
{
'details1': {Name: "John", CountryName: "US", value: 2},
'details2': {Name: "David", CountryName: "AUS", value: 3},
'details3': {Name: "Bob", CountryName: "UK", value: 4},
};
I did something like this already but could not figure it out
Object.fromEntries(Object.entries(studentDetails).map(([key,
value]) => [key, some data transformation on value]))
You can do something like this. We define a transformValue function which takes in the student details object and any transform function. Then applies the transform function on every value and returns the whole transformed details object.
const studentDetails = {details1: { Name: "John", CountryName: "US", value: 1 }, details2: { Name: "David", CountryName: "AUS", value: 2 }, details3: { Name: "Bob", CountryName: "UK", value: 3 }};
const transformValue = (details, transform) => {
return Object.entries(details).reduce((acc, [key, detail]) => {
acc[key] = {
...detail,
value: transform(detail.value)
}
return acc;
}, {});
};
console.log(transformValue(studentDetails, (val) => val + 1)); // Increments value
console.log(transformValue(studentDetails, (val) => val * val)); // Squaring values
A solution that doesn't involve Object.fromEntries or reduce. Just iterate over the object, adding updated objects to output, and then returning output.
const data={details1:{Name:"John",CountryName:"US",value:1},details2:{Name:"David",CountryName:"AUS",value:2},details3:{Name:"Bob",CountryName:"UK",value:3}};
const increment = (n) => n + 1;
const decrement = (n) => n - 1;
function transform(data, prop, fn) {
const output = {};
for (const key in data) {
output[key] = {
...data[key],
[prop]: fn(data[key][prop])
};
}
return output;
}
const update1 = transform(data, 'value', increment);
const update2 = transform(update1, 'value', decrement);
console.log(update1);
console.log(update2);
I want to counting duplicate item in my array of object,I usse this code below but I have this error :
//TypeError: Cannot read properties of undefined (reading 'type')
//this is my array
data[
1:{cs:'10', name:'a' , age},
2:{cs:'20', name :'b', age:'25'},
3:{cs:'10', name :'h', age:'51'},
4:{cs:'10', name :'g', age:'30'},
...]
//this is my result that i want
finalArray[
{cs:'10', count :3},
{cs:'20', count :1 },
...]
TypeError: Cannot read properties of undefined (reading 'type')
const prepareSeries = (data, sectors) => {
let finalArray = [{}];
const map = new Map();
finalArray.forEach(function (stockItem) {
if (map.has(stockItem.cs)) {
map.get(stockItem.cs).count++;
} else {
map.set(stockItem.cs, Object.assign(stockItem, { count: 1 }));
}
});
finalArray = [...map.values()];
const result = Object.entries(finalArray)
.sort((a, b) => b[1] - a[1])
.slice(0, 10);
return [
console.log(result),
];
};
As I understand it, you want to count the occurrences of unique cs values in your data array? Sure thing.
const data = [
{ cs: "10", name: "a", age: "72" },
{ cs: "20", name: "b", age: "25" },
{ cs: "10", name: "h", age: "51" },
{ cs: "10", name: "g", age: "30" },
];
const countsByCs = {};
data.forEach(({ cs }) => {
countsByCs[cs] = (countsByCs[cs] || 0) + 1;
});
const finalArray = Object.entries(countsByCs)
.map(([cs, count]) => ({ cs, count }))
.sort((a, b) => b.count - a.count);
console.log(finalArray);
outputs
[
{ cs: '10', count: 3 },
{ cs: '20', count: 1 }
]
First, do the counts using Array.prototype.reduce() then sort using Array.prototype.sort().
The following would also work.
const data = [
{ cs: "10", name: "a", age: "31" },
{ cs: "20", name: "b", age: "25" },
{ cs: "10", name: "h", age: "51" },
{ cs: "10", name: "g", age: "30" },
];
const output = Object.entries(
data.reduce((prev, { cs }) => {
prev[cs] = prev[cs] ? prev[cs] + 1 : 1;
return prev;
}, {})
)
.map(([cs, count]) => ({ cs, count }))
.sort((a, b) => b.count - a.count);
console.log(output);
Swap a and b in b.count - a.count, if you want to change the order of sorting.
I have an array like so
let items = [
{name: "1"},
{name: "2"},
{name: "3"},
{unwrap: true,
items: [
{name: "4"},
{name: "5"},
{name: "6"},
]
},
{name: "7"},
]
How can I flatten the unwrap object to get the following output?
items = [
{name: "1"},
{name: "2"},
{name: "3"},
{name: "4"},
{name: "5"},
{name: "6"},
{name: "7"},
]
I thought I could do something like this:
items.map(item => {
if(item.hasOwnProperty("unwrap")){
return ... item.items
}
return item
})
However the ...s don't work as a return value.
I have come up with the somewhat clunky using a second array like so:
let output = []
items.forEach((item) => {
if (!item) {
return;
}
if (item.hasOwnProperty("unwrap")) {
return output.push(...item.contents);
}
return output.push(item);
});
flatMap is what you need.
const items=[{name:"1"},{name:"2"},{name:"3"},{unwrap:!0,items:[{name:"4"},{name:"5"},{name:"6"}]},{name:"7"}];
const result = items.flatMap(item => {
if (item.hasOwnProperty('unwrap')) {
return item.items;
}
return item;
});
console.log(result);
You can rely on flatMap:
items.flatMap((x) => {
if (!x.unwrap) {
return x;
}
return x.items;
});
Another way using reduce()
let items = [{name: "1"}, {name: "2"}, {name: "3"}, {unwrap: true, items: [{name: "4"}, {name: "5"}, {name: "6"}, ] }, {name: "7"}, ];
const res = items.reduce((p, c) => p.concat(c.items || c), []);
console.log(res);
Since obj.items won't exist on the regular objects, we can use the || operator to get the desired items, then concat those to the final array.
another way is:
items.flatMap(item=> item?.unwrap ? item.items: item )
or
const result = items.flatMap(item=> item?.unwrap ? item.items: item )
I got an array of id's. I also have another array of objects. I would like to remove those objects which match with the array of id's. Below is the pseudo code for the same. Can someone help me with the best approch?
const ids = ['1', '2'];
const objs = [
{
id: "1",
name : "one",
},
{
id: "1",
name : "two"
},
{
id: "3",
name : "three",
},
{
id: "4",
name : "four"
},
];
ids.forEach(id => {
const x = objs.filter(obj => obj.id !== id )
console.log('x ==', x);
});
Use filter and includes method
const ids = ["1", "2"];
const objs = [
{
id: "1",
name: "one",
},
{
id: "1",
name: "two",
},
{
id: "3",
name: "three",
},
{
id: "4",
name: "four",
},
];
const res = objs.filter(({ id }) => !ids.includes(id));
console.log(res);
You can put the ids in a Set and use .filter to iterate over the array of objects and .has to check if the id is in this set:
const ids = ['1', '2'];
const objs = [
{ id: "1", name : "one" },
{ id: "1", name : "two" },
{ id: "3", name : "three" },
{ id: "4", name : "four" },
];
const set = new Set(ids);
const arr = objs.filter(obj => !set.has(obj.id));
console.log(arr);
1st requirement -> you have to check for all elements in id array
way to do that using array's built in method is array.includes() or indexof methods
2nd Requirement -> pick out elements not matching with ur 1st requirement which means filter the array.
Combile two
arr = arr.filter(x => !ids.includes(x.id))
Cool es6 destructung syntax
arr = arr.filter(({id}) => !ids.includes(id))
const ids = ['1', '2'];
const objs = [
{
id: "1",
name : "one",
},
{
id: "1",
name : "two"
},
{
id: "3",
name : "three",
},
{
id: "4",
name : "four"
},
];
let arr = objs.filter(function(i){
return ids.indexOf(i.id) === -1;
});
console.log(arr)
I use the following reduce:
const data = this.forms.reduce((accumulator, current) => {
return (accumulator[current.name] = current.value);
}
}, {});
Where this.forms is:
[
{value: {document: "fsfsf", seria: "fsfsfsf"}, "name": "Form1"},
{value: {seria: "AA", age: "45"}, "name": "Form2"},
{value: {marry: "yes", hobby: "AAA"}, "name": "Form3"}
]
I need to build this result:
{
"Form1": {document: "fsfsf", seria: "fsfsfsf"},
"Form2": {seria: "AA", age: "45"},
"Form3": {marry: "yes", hobby: "AAA"}
}
But I get wrong result:
{
{document: "fsfsf", seria: "fsfsfsf"},
"Form2": {}
}
I can not get why?
The callback function to the accumulator for reduce must return the accumulator to be applied to subsequent elements in the array. Returning the result of an assignment expression returns the result of the expression (current.value in this case), not the accumulator.
const forms = [
{value: {document: "fsfsf", seria: "fsfsfsf"}, "name": "Form1"},
{value: {seria: "AA", age: "45"}, "name": "Form2"},
{value: {marry: "yes", hobby: "AAA"}, "name": "Form3"}
];
const data = forms.reduce((accumulator, current) => {
accumulator[current.name] = current.value;
return accumulator;
}, {});
console.log(data);