Object.assign nested array with only certain properties - javascript

I have json data from below. The goal is to take all the Orders and combine them into one array while maintaining the Amount and the IdNumber so that I can use lodash _.groupBy on the Type.
In the end I'll have, for example, Type: test with each IdNumber and the Order Amounts that correspond to that IdNumber
I tried Object.assign on the data and did
data.forEach(d => {
let orders = d['Orders'];
let newOrders = Object.assign({}, {Idnumber: data.IdNumber, Orders: orders});
let groupedOrders = _.groupBy(newOrders, 'Type');
});
But, I'm not sure how to get just the Amount and Type of orders and merge them into one array. I'm also unclear if Object.assign is keeping track of the IdNumber with the Orders. when going through the array. I've never used Object.assign so perhaps that isn't even the right method to go about what I need.
Json data:
data = [
{
"Name": "abc",
"Amount": 3000,
"Idnumber": "001",
"Date": "11/17/2017",
"Orders": [
{
"Order Number": "11",
"Date": "11/18/2017",
"Amount": 1000,
"Type": "test"
},
{
"Order Number": "12",
"Date": "12/31/2017",
"Amount": 2000,
"Type": "trial"
}
],
"foo": "foo",
"foo2": foo,
"foo3": "foo",
"foo4": "foo"
},
{
"Name": "def",
"Amount": 5000,
"Idnumber": "002",
"Date": "12/15/2017",
"Orders": [
{
"Order Number": "10",
"Date": "11/02/2017",
"Amount": 7600,
"Type": "trial"
},
{
"Order Number": "16",
"Date": "05/31/2018",
"Amount": 15000,
"Type": "interim"
}
],
"foo": "foo",
"foo2": foo,
"foo3": "foo",
"foo4": "foo"
}
]

You can use array#reduce and array#map to inject Idnumber to each order and later on use array#reduce to group data based on the Type.
const data = [{"Name":"abc","Amount":3000,"Idnumber":"001","Date":"11/17/2017","Orders":[{"Order Number":"11","Date":"11/18/2017","Amount":1000,"Type":"test"},{"Order Number":"12","Date":"12/31/2017","Amount":2000,"Type":"trial"}],"foo":"foo","foo2":"foo","foo3":"foo","foo4":"foo"},{"Name":"def","Amount":5000,"Idnumber":"002","Date":"12/15/2017","Orders":[{"Order Number":"10","Date":"11/02/2017","Amount":7600,"Type":"trial"},{"Order Number":"16","Date":"05/31/2018","Amount":15000,"Type":"interim"}],"foo":"foo","foo2":"foo","foo3":"foo","foo4":"foo"}];
var result = data.reduce((r, {Orders, Idnumber}) => {
let orders = Orders.map(order => Object.assign({}, order, {Idnumber}));
return r.concat(orders);
},[]);
console.log(result);
console.log('--------------Grouped By----------');
var groupedBy = result.reduce((r,o) => {
r[o.Type] = r[o.Type] || [];
r[o.Type].push(o)
return r;
},{});
console.log(groupedBy);
.as-console-wrapper { max-height: 100% !important; top: 0; }

newOrder = data.map(d => ({Orders: d.Orders, idNumber: d.Idnumber}))

Related

How to compare and manipulate json object [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I need to compare and manipulate JSON objects.
First object
let data1 = {
"id": "111",
"entity_id": "222",
"text_id": "333",
"details": [{
"value": 1000,
"comp_id": "444",
"CompName": "driving"
}]
}
Second object
let data2 = [{
"id": "111",
"text_id": "333",
"criteria_type": "TXT",
"value": 1000,
"comp": {
"id": "444",
"name": "driving"
}
}, {
"id": "222",
"text_id": "444",
"criteria_type": "TXT",
"value": 2000,
"comp": {
"id": "555",
"name": "swiming"
}
}]
There are 2 objects data1 and data2. Here, I need to compare the data1.details array with the data2 array key => data1.details.comp_id with data2.comp.id if not match then I need to push value, id and name to data1 object. Please help me to resolve this issue.
Resulting object
data1 will be:
{
"id": "111",
"entity_id": "222",
"text_id": "333",
"declaration_details": [{
"value": 1000,
"comp_id": "444",
"CompName": "driving",
}, {
"value": 2000,
"comp_id": "555",
"CompName": "swiming",
}]
}
Based on your expected result, wouldn't you just need to map data2 to the declaration_details of the resulting object?
const main = () => {
const { details, ...rest } = data1;
const result = {
...rest,
fbp_year: new Date().getUTCFullYear(),
declaration_details: data2.map(({
value,
comp: {
id: comp_id,
name: CompName
}
}) => ({
value,
comp_id,
CompName
}))
};
console.log(result);
};
const
data1 = {
"id": "111",
"entity_id": "222",
"text_id": "333",
"details": [{
"value": 1000,
"comp_id": "444",
"CompName": "driving"
}]
},
data2 = [{
"id": "111",
"text_id": "333",
"criteria_type": "TXT",
"value": 1000,
"comp": {
"id": "444",
"name": "driving"
}
}, {
"id": "222",
"text_id": "444",
"criteria_type": "TXT",
"value": 2000,
"comp": {
"id": "555",
"name": "swiming"
}
}];
main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
Use filter() to find objects in the data2 matching comp.id. Then you can just use map() to create a new array. Finally, you can add the mappedData2 array to the data1 in declaration_details.
let filteredData2 = data2.filter(item => {
return data1.details.some(detail => detail.comp_id === item.comp.id);
});
let mapData = filteredData2.map(item => {
return {
value: item.value,
comp_id: item.comp.id,
CompName: item.comp.name
};
});
You can use JSON.stringify(yourJsonObject) to convert your objects to strings.
Then you can compare them like this. areEqual = string1 == string2. Make sure the object properties are in the same order for both objects.

How can i filter result if i have array in body

i have a payload
{
"category": "Mobile",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
}
i want to find all object which have rating 1 or 2 or 3 and also have any location
Basically i am creating a filter for an ecommerce store i which we will get multiple location and multiple ratings as well so we will return only those object which have matched property. i am attaching a screenshot of UI for better understanding.
i want to run this filter with multiple location and multiple checked checkbox
You can do create a filter dynamically:
const { category, price, location, rating } = req.body;
const filter = {};
if (category) filter.category = category;
if (price) filter.price = { $gte: parseInt(price.from, 10), $lte: parseInt(price.to, 10) };
if (location?.length) filter.location = { $in: location };
if (rating?.length) filter.rating = { $in: rating };
const data = await Collection.find(filter);
If you want to filter your objects, you should use filter() from your array :
const arr = [{
"category": "Mobile1",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"1",
"2",
"3"
]
},
{
"category": "Mobile2",
"price": {
"from": "10",
"to": "50"
},
"location": [
"Jakrta",
"Bandung",
"Surabaya"
],
"rating": [
"2",
"3"
]
}];
const result = arr.filter(el => el.rating.includes("1") || el.rating.includes("2") || el.rating.includes("3"));
console.log(result);

Is there a way to compare dates and store them in an array?

I'm currently working on a website where Objects are sorted. The Objects are from a database where it's stored with a date (2022-10-13 02:07:11). Is there a way to compare dates and store the ones that are created on the same date? For example: If there are two objects that were created on 2022-10-13, but with at a different time, I would like to save these in an array with the name of the date.
I can't change how it's saved because it's not my DB.
I hope you understand how I mean it.
(I don't know how you want it or how your database is exactly so you might have to change some things)
Try using (something like) this:
let sorted = {};
// replace "data" below with your key
for(key in data){
if(!sorted[data[key].date]){
sorted[data[key].date] = [];
}
sorted[data[key].date].push({key: data[key]});
}
Example in my case:
let data = {
"a": {
"date": "2022-10-13 02:07:11"
},
"b": {
"date": "2022-10-13 00:00:00"
},
"c": {
"date": "2022-10-10 02:07:11"
}
};
let sorted = {};
for (key in data) {
if (!sorted[data[key].date]) {
sorted[data[key].date] = [];
}
sorted[data[key].date].push({
key: data[key]
});
}
console.log(sorted);
A reduce is useful here
Give us more details of the object to give a more tailored answer
const obj = [
{ "id": "a1", "date": "2022-10-13 01:07:11" },
{ "id": "a2", "date": "2022-10-13 02:07:11" },
{ "id": "a3", "date": "2022-10-13 03:07:11" },
{ "id": "b", "date": "2022-10-14 02:07:11" },
{ "id": "c1", "date": "2022-10-15 01:07:11" },
{ "id": "c2", "date": "2022-10-15 02:07:11" },
{ "id": "c3", "date": "2022-10-15 03:07:11" },
{ "id": "d", "date": "2022-10-16 01:07:11" }
];
const grouped = obj.reduce((acc,cur) => {
const key = cur.date.split(" ")[0];
(acc[key] = acc[key] || []).push(cur);
return acc;
},{})
console.log(grouped);

Removing duplicate value from list of javascript objects in react js

I have react project and in that have a javascript array of object similar to given below and in that object it has a value called category.
const data = [{
"id": 1,
"item": "760",
"price": "$609.05",
"category": "BMW"
}, {
"id": 2,
"item": "Frontier",
"price": "$317.89",
"category": "Nissan"
}, {
"id": 3,
"item": "Odyssey",
"price": "$603.64",
"category": "BMW"
}]
Im mapping through the list and displaying the category as shown below.
{data.map(item => (<span>{item.category}</span>))}
Here, the category duplicates and display several times when there are several similar items. Considering the given data list, the category BMW display twice.
What I want is, even if there are multiple similar categories, I only want to display once. Is this possible and how can I do it?
You could add your categories into a Set
const data = [{
"id": 1,
"item": "760",
"price": "$609.05",
"category": "BMW"
}, {
"id": 2,
"item": "Frontier",
"price": "$317.89",
"category": "Nissan"
}, {
"id": 3,
"item": "Odyssey",
"price": "$603.64",
"category": "BMW"
}]
let categories = new Set()
data.forEach(entry => {categories.add(entry.category) })
categories.forEach(cat => console.log(cat))
There can be various ways to reach the desired result. I would do it with a Set() and destructuring syntax:
{[...new Set(data.map(item => (<span>{item.category}</span>)))]}
const data = [{
"id": 1,
"item": "760",
"price": "$609.05",
"category": "BMW"
}, {
"id": 2,
"item": "Frontier",
"price": "$317.89",
"category": "Nissan"
}, {
"id": 3,
"item": "Odyssey",
"price": "$603.64",
"category": "BMW"
}]
const newData = [...new Set(data.map(item => ("<span>" + item.category + "</span>")))]
console.log(newData);
you can use {data.find(item => (<span>{item.category}</span>))}. The find() method returns the first element in the provided array that satisfies the provided testing function
You can use the filter
let array= data.filter((v,i,a)=>a.findIndex(v2=>(v2.category===v.category))===i)
and
{array.map(item => (<span>{item.category}</span>))}
const data = [{
"id": 1,
"item": "760",
"price": "$609.05",
"category": "BMW"
}, {
"id": 2,
"item": "Frontier",
"price": "$317.89",
"category": "Nissan"
}, {
"id": 3,
"item": "Odyssey",
"price": "$603.64",
"category": "BMW"
}]
function getUniqueArrayBy(arr, key) {
return [...new Map(arr.map(item => [item[key], item])).values()]
}
const filtered = getUniqueArrayBy(data, 'category');
console.log(filtered);
Use native methods .reduce and .map of Array in chain.
const categories = data.reduce((acc, {category}) => {
if (!acc.includes(category)) { // check if there's not such value in accumulator
acc.push(category); // adding category
}
return acc; // returning value
}, []) // [] is an accumulator value
.map(category => <span>{category}</span>); // iterating over result
Piece a cake.

Handle Array of Object manipulation

Below I have an array of objects
var data = [{
"time": "1572024707.4763825",
"rssi": "32",
"id": "77777"
}, {
"time": "1572024709.0991757",
"rssi": "32",
"id": "77777"
}, {
"time": "1572024704.4570136",
"rssi": "32",
"id": "555555"
}, {
"time": "1572024708.3903246",
"rssi": "32",
"id": "77777"
}, {
"time": "1572024699.7132683",
"rssi": "32",
"id": "66666"
}]
How can I restructure it to remove the repeating id's with the oldest time
I tried to pull all the unique IDs from the array so I can loop through the data array but then the code started to get too long.
data.forEach(item => {
IDs.push(item.id);
});
var unqIDs = [...new Set(IDs)];
console.log(unqIDs);
the output should look like this
outPutShouldBe = [{
"time": "1572024699.7132683",
"rssi": "32",
"id": "66666"
},{
"time": "1572024709.0991757",
"rssi": "32",
"id": "77777"
}, {"time": "1572024704.4570136",
"rssi": "32",
"id": "555555"
}
]
Create an object mapping ids to the item w/ the earliest time of those with that id:
var keydata = {};
data.forEach(item=>{
var p = keydata[item.id];
if ( !p || p.time>item.time ) {
keydata[item.id] = item;
}});
Now gather up the values in that object:
var newdata = [];
for ( var k in keydata ) {
newdata.push(keydata[k]);
}
or the more elegant (thanks, #TulioF.):
var newdata = Object.values(keydata)
Using forEach() find() filter() and filter() to decide which element to return
var data = [{"time": "1572024707.4763825","rssi": "32","id": "77777"},{"time": "1572024709.0991757","rssi": "32","id": "77777"}, {"time": "1572024704.4570136","rssi": "32","id": "555555"}, {"time": "1572024708.3903246","rssi": "32","id": "77777"}, {"time": "1572024699.7132683","rssi": "32","id": "66666"}]
let resultsArray = []
data.forEach(obj=>{
const foundObj = resultsArray.find(data => data.id === obj.id)
if(foundObj && new Date(foundObj.time) > new Date(obj.time)){
const filteredArray = resultsArray.filter(data => data.id === obj.id)
resultsArray = [...filteredArray , foundObj]
} else if (!foundObj){
resultsArray.push(obj)
}
})
console.log(resultsArray)
You coud take an object as hash table and get the values directly.
var data = [{ time: "1572024707.4763825", rssi: "32", id: "77777" }, { time: "1572024709.0991757", rssi: "32", id: "77777" }, { time: "1572024704.4570136", rssi: "32", id: "555555" }, { time: "1572024708.3903246", rssi: "32", id: "77777" }, { time: "1572024699.7132683", rssi: "32", id: "66666" }],
result = Object.values(data.reduce((r, o) => {
if (!r[o.id] || +r[o.id].time > +o.time) r[o.id] = o;
return r;
}, {}));
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
use lodash to sort the array in descending order or ascending order as per your need (desc, asc) and get the zeroth object. try something like this. filter and orderBy
var data = [{
"time": "1572024707.4763825",
"rssi": "32",
"id": "77777"
}, ....];
let idsSet = new Set();
data.map(item=> idsSet.add(item.id));
let idsArr = Array.from(idsSet);
let newArr = [];
idsArr.map(id=>{
let tempArray = data.filter(item => item.id === id);
return newArr.push((_.orderBy(tempArray, ['time'],['desc']))[0]);
} )
console.log(newArr);
console output
[ {
"time": "1572024709.0991757",
"rssi": "32",
"id": "77777"
}, {
"time": "1572024704.4570136",
"rssi": "32",
"id": "555555"
}, {
"time": "1572024699.7132683",
"rssi": "32",
"id": "66666"
}];
Here you can do something like this :
let existMap = {};
data.filter(val => {
if((val.id in existMap) && (val.time>existMap[val.id])) return;
else{
existMap[val.id] = val.time;
return true;
}
})
console.log(result)
The condition can be changed based on requirement. just want to reference for your problem.

Categories

Resources