Re-arrange a JSON object - javascript

I have data that comes from the database looking like:
[
{
ID: 1,
UPC: 11111,
Qty: 1,
Price: 1.99
},
{
ID: 2,
UPC: 11111,
Qty: 2,
Price: 1.99
},
{
ID: 3,
UPC: 22222,
Qty: 1,
Price: 9.99
},
{
ID: 4,
UPC: 11111,
Qty: 3,
Price: 1.99
},
{
ID: 5,
UPC: 22222,
Qty: 9,
Price: 9.99
}
]
Within the page, if they click a button, I need to rearrange it to look like this:
[
{
UPC: 11111,
Qty: 6,
Price: 1.99
},
{
UPC: 22222,
Qty: 10,
Price: 9.99
}
]
How can I convert this? 99% of the time I need the original dataset, so initially returning it like the 2nd dataset is not an option.
TIA.

Using the link posted above in the comments, I managed to make this work. I feel like there is probably a more efficient way using Underscore.js, but since I can't figure it out, this will do.
var tmpItems = {};
for (var i = items.length; i--;)
{
// init an array, if it is not there
tmpItems[it.All[i]['UPC']] = tmpItems[it.All[i]['UPC']] || [];
tmpItems[it.All[i]['UPC']]['Qty'] = (tmpItems[it.All[i]['UPC']]['Qty'] || 0) + (it.All[i]['Qty'] || 0);
tmpItems[it.All[i]['UPC']]['Price'] = (it.All[i]['Price'] || 0);
}
// convert back to an object
var newItems = [];
for (var key in tmpItems)
{
if (tmpItems.hasOwnProperty(key))
{
newItems.push({ 'UPC': key, 'Qty': tmpItems[key]['Qty'], 'Price': tmpItems[key]['Price'] });
}
}

Related

How do I check that the correct objects are being returned via a function (expect function returns [Function Anonymous])?

I have a function:
const sort =
(pets,attribute) =>
_(pets)
.filter(pets=> _.get(pets, attribute) !== null)
.groupBy(attribute)
.value()
Some data:
const pets= [{
id: 1,
name: 'snowy',
},
{
id: 2,
name: 'quacky',
},
{
id: 3,
name: 'snowy',
age: 5,
},
{
id: null,
name: null,
age: null
}
]
const attribute = 'name'
I am currently trying to write some Jest unit tests for this, that tests if the function returns the correct resultant object after being sorted based off an attribute.
The result of:
sort(pets,attribute) is something like this:
{
snowy: [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5} ],
quacky: [ { id: 2, name: 'quacky' } ]
}
Is there a way I can do a expect to match the two objects snowy and quacky here?
The thing I want to test for is that the objects are being correctly grouped by the key.
I've tried using something like
const res = sort(users,key)
expect(res).toEqual(
expect.arrayContaining([
expect.objectContaining({'snowy' : [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5 } ]},
expect.objectContaining({'quacky' : [ { id: 2, name: 'quacky' } ]}))
])
)
which doesn't seem to work, the received output seems to output:
Expected: ArrayContaining [ObjectContaining {"snowy": [{"id": 1, "name": "snowy"}, {"age": 5, "id": 3, "name": "snowy"}]}]
Received: [Function anonymous]
I am unsure what the best method to test this kind of function is either so advice on that would be appreciated.
If this is what your arrangeBy() returns:
{
snowy: [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5} ],
quacky: [ { id: 2, name: 'quacky' } ]
}
Then you can just do:
const expected = {
snowy: [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5} ],
quacky: [ { id: 2, name: 'quacky' } ]
}
const res = arrangeBy(users,key)
expect(res).toEqual(expected)
But looking at your Error message I guess you have something else mixed up. In the beginning you listed the implementation of a sort function which seems to not be used in the test. Where is arrangeBy coming from now.
Please provide more code examples.

How to combine objects with same value in an array?

How can I merge my array of objects with same value? I have got orders array, which may have the same product. If so, I want to merge them and add the quantity.
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
]
Expected output:
orders = [
{
product: "chair",
quantity: 7,
price: 900,
}
]
Goal: Group object array by product and add the quantity.
Here is one of the performant way to achieve that:
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
];
const resultTest = {};
const result = [];
orders.forEach((item) => {
if (resultTest[item.product]) {
const index = resultTest[item.product] -1;
const foundItem = result[index];
const newValue = {
...foundItem,
quantity: foundItem.quantity + item.quantity,
};
result[index] = newValue;
} else {
resultTest[item.product] = result.length + 1;
result.push(item);
}
});
console.log(result);
I think you can do this like ths
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
]
var output=new Array;
orders.forEach(elem=>{
var found =false;
for(var i =0; i<output.length;i++)
{
if(output[i].product==elem.product)
{
output[i].quantity+=elem.quantity;
var found = true;
break;
}
}
if(!found)
{
output.push(elem);
}
})
console.log(output);
Here is my solution in more cleaner way:
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
{
product: "table",
quantity: 1,
price: 1000,
}
]
const combineSimilarOrders = {};
orders.forEach((order) => {
if (!(order.product in combineSimilarOrders)) {
combineSimilarOrders[order.product] = [ { ...order } ]
}
else {
if (order.product in combineSimilarOrders) {
let product = Object.keys(combineSimilarOrders);
combineSimilarOrders[product][0].quantity += order.quantity;
combineSimilarOrders[product][0].price += order.price;
}
else {
combineSimilarOrders[order.product].push(order);
}
}
});
console.log(combineSimilarOrders);
Output:
{
chair: [ { product: 'chair', quantity: 7, price: 1800 } ],
table: [ { product: 'table', quantity: 1, price: 1000 } ]
}

Javascript re-order array of object by value

How do I re-order array of object showing below by follow value. If follow value is not -1, move the item below to the item that has the id value same as follow value.
Here is the example.
let charObj = [
{ id: 8, name: 'Catelyn Stark', follow: -1 },
{ id: 7, name: 'Jaime Lannister', follow: 8 },
{ id: 3, name: 'Jon Snow', follow: -1 },
{ id: 4, name: 'Daenerys Targaryen', follow: 7 },
{ id: 5, name: 'Sansa Stark', follow: 4 }
];
Expected output will be;
let charObj = [
{ id: 8, name: 'Catelyn Stark', follow: -1 },
{ id: 7, name: 'Jaime Lannister', follow: 8 },
{ id: 4, name: 'Daenerys Targaryen', follow: 7 },
{ id: 5, name: 'Sansa Stark', follow: 4 },
{ id: 3, name: 'Jon Snow', follow: -1 }
];
Not sure if I can use sort(). What is the best way to re-order this object?
I think this will do what you're asking. I'm sure it could be made more efficient, but unless your list gets quite large that shouldn't make much practical difference. Also, this assumes any character will only have one follower. If that's not the rule, then the function will have to be adjusted.
let charObj = [
{ id: 8, name: "Catelyn Stark", follow: -1 },
{ id: 7, name: "Jaime Lannister", follow: 8 },
{ id: 3, name: "Jon Snow", follow: -1 },
{ id: 4, name: "Daenerys Targaryen", follow: 7 },
{ id: 5, name: "Sansa Stark", follow: 4 }
];
function sortChars(chars) {
let result = [];
let leaders = chars.filter(c => c.follow === -1);
for (let i = 0; i < leaders.length; i++) {
let current = leaders[i];
while (current) {
result.push(current);
let next = charObj.find(c => c.follow === current.id);
current = next;
}
}
return result;
}
console.log(sortChars(charObj));

Max element in an array in dailogflow

I am trying to calculate max element in an array . I tried this code but it is returning [object Object]
Is there something i am missing while doing in dailogflow.
function studentgroup(agent){
let games = [
{ id: 1, name: 'Star Wars: Imperial Assault', votes: 3},
{ id: 2, name: 'Game of Thrones: Second Edition', votes: 4 },
{ id: 3, name: 'Merchans and Marauders', votes: 5 },
{ id: 4, name: 'Eclipse', votes: 6 },
{ id: 5, name: 'Fure of Dracula', votes: 2 }
];
let maxGame = games.reduce((max, game) => max.votes > game.votes ? max : game);
agent.add(`${maxGame}`);
}
You can simply find the maximum element by iterating over the array.
let games = [
{ id: 1, name: 'Star Wars: Imperial Assault', votes: 3},
{ id: 2, name: 'Game of Thrones: Second Edition', votes: 4 },
{ id: 3, name: 'Merchans and Marauders', votes: 5 },
{ id: 4, name: 'Eclipse', votes: 6 },
{ id: 5, name: 'Fure of Dracula', votes: 2 }
];
maxElement = -Infinity;
element = null
for (const game of games) {
if (game.votes > maxElement) {
maxElement = game.votes;
element = game;
}
}
console.log(element)
The issue is that maxGame is an object. Using your example, that object will be
{ id: 4, name: 'Eclipse', votes: 6 }
But agent.add() is expecting to send back a string. The default "string" form of an object is "[object Object]", as you've seen.
You probably want to return something that makes more sense when displayed or read aloud, so it might make more sense for that line to be something like
agent.add(`The winner, with ${maxElement.votes} votes, is ${maxElement.name}.`)
which, given the example, would say something like
The winner, with 6 votes, is Eclipse.

JSON.stringify throws error

var Products = [
{ id: 0, product: 'Sour Apple', price: 10, count: 1, product_thumb: 'resources/css/apple.png' },
{ id: 1, product: '30 dsfdf', price: 20, count: 1, product_thumb: 'resources/css/croissant.png' },
{ id: 2, product: 'Discount Coffee', price: 30, count: 1, product_thumb: 'resources/css/coffecup.png' },
{ id: 3, product: '30 Donut Combo', price: 40, count: 1, product_thumb: 'resources/css/donut.png' },
{ id: 4, product: 'Invisishield', price: 50, count: 1, product_thumb: 'resources/css/apple.png' },
{ id: 5, product: 'Pink Cupcake', price: 60, count: 1, product_thumb: 'resources/css/icecream.png' },
{ id: 6, product: 'Strawberry Cone', price: 70, count: 1, product_thumb: 'resources/css/softy.png' }
]
I am trying to encode the product array (above) to JSON string and I am getting the following error: TypeError: Converting circular structure to JSON
UPDATE (from comment):
What i am trying to do is, i declare a var product = []; and then as and when user add's product to cart i do: var productObject = { id: id, product: name, price: price, count: 1, product_thumb: img }; Once the user says done, i take the array and want to convert it to json and send it to my web service. The problem is when i do JSON.stringify it gives that error. product.push(productObject);
TypeError: Converting circular structure to JSON
This error occurs when you have a cycle in your object. For example :
var obj = {};
obj.a = {b:obj};
If you browse obj, you have that cycle : obj->a->b->obj->...
So, JSON.stringify(obj) raises an error.
That kind of error can also occur when you include a DOM Object (window, document...), since they or their children reference them(self).
What browser? What environment? Just plugged your data into Chrome Inspector, works fine..

Categories

Resources