how do i find the toal orders in this format - javascript

i am getting an output
[] [] [] [] [] [] [] [] [] [] [ { order_status: 'Received' } ] [{ order_status: '1' },{ order_status: '1'},{ order_status: 'Accepted'}] [] [] [] [] [] [] [] [] [ { order_status: 'Received' } ] [] [ { order_status: 'Accepted' } ] []
I need to find the total order, if it has an empty array, display 0 else display number of objects. This is my final output i need.
0 0 0 0 0 0 0 0 0 0 1 3 0 0 0 0 0 0 0 0 1 0 1 0

Use Array#map and get the length of each array.
let arr = [[], [], [], [], [], [], [], [], [], [], [ { order_status: 'Received' } ], [{ order_status: '1' },{ order_status: '1'},{ order_status: 'Accepted'}], [], [], [], [], [], [], [], [], [ { order_status: 'Received' } ], [], [ { order_status: 'Accepted' } ], [] ];
let res = arr.map(x => x.length);
console.log(JSON.stringify(res));

Related

I want to combine the values ​of objects in different arrays by sorting them one side

I want to concatenate the values ​​of objects in different arrays to one side.
I tried to output the data value received in json to console.log.
I want to put the values ​​in the Ingredient List into the List array.
console.log(detail);
{
List: [
{
id: 120,
content: "stack-overflow",
functionalList: [
{
id: 832,
},
],
},
{
id: 230,
content: "heap-overflow",
functionalList: [
{
id: 24,
},
],
},
],
ListValue: [
{
IngredientList: [
{
id: 1,
value: 43
},
{
id: 23,
value: 23
},
],
},
],
},
]);
I want to put ListValue -> IngredientList value values ​​into List array object.
How can I do it this way? I've been trying all day, but it's hard for me.
{
List: [
{
id: 120,
content: "stack-overflow",
value: 43
functionalList: [
{
id: 832,
functionalId: 37
},
],
},
{
id: 230,
content: "heap-overflow",
value: 23
functionalList: [
{
id: 24,
functionalId: 12
},
],
},
],
ListValue: [
{
IngredientList: [
{
id: 1,
value: 43
},
{
id: 23,
value: 23
},
],
},
],
},
]);
This should work in a mutable approach, even if you have multiple objects inside ListValue:
data.List = [
...data.List,
...data.ListValue.reduce((arr, el) => {
arr.push(...el.IngredientList);
return arr;
}, []),
];
It's not clear which value of the IngredientList should go in which item of List. Supposing you always want to pair the first value with the first item, the second with the second, and so on...
const obj = {
List: [
{
id: 120,
content: "stack-overflow",
functionalList: [
{
id: 832,
},
],
},
{
id: 230,
content: "heap-overflow",
functionalList: [
{
id: 24,
},
],
},
],
ListValue: [
{
IngredientList: [
{
id: 1,
value: 43,
},
{
id: 23,
value: 23,
},
],
},
],
};
const ingridientsValue = obj.ListValue[0].IngredientList.map(el => el.value); // [43, 23]
for (const item of obj.List) item.value = ingridientsValue.shift();
console.log(obj.List);
I have solved this. Check it out here: https://jsfiddle.net/bowtiekreative/o5rhy7c1/1/
First your JSON needs to be validated.
Remove the ")" and the extra ","
Instructions
Create an empty array called arr.
Loop through the ListValue array.
For each item in the ListValue array, loop through the IngredientList array.
For each item in the IngredientList array, push the value property into the arr array.
Log the arr array to the console.
Example:
var json = {
"List":[
{
"id":120,
"content":"stack-overflow",
"functionalList":[
{
"id":832
}
]
},
{
"id":230,
"content":"heap-overflow",
"functionalList":[
{
"id":24
}
]
}
],
"ListValue":[
{
"IngredientList":[
{
"id":1,
"value":43
},
{
"id":23,
"value":23
}
]
}
]
};
var arr = [];
for (var i = 0; i < json.ListValue.length; i++) {
for (var j = 0; j < json.ListValue[i].IngredientList.length; j++) {
arr.push(json.ListValue[i].IngredientList[j].value);
}
}
console.log(arr)

Extract ranges from sequential values [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 months ago.
Improve this question
Task 1:
I have my collection with documents in mongodb with value from sequential ranges as follow :
{x:1}
{x:2}
{x:3}
{x:5}
{x:6}
{x:7}
{x:8}
{x:20}
{x:21}
I need to extract a list of sequential ranges in the form(the count is not compulsory , but I need at least the first and last values from the range):
{x:[1,3] , count:3}
{x:[5,8], count:4}
{x:[20,21],count:2}
or
{ min:1 , max:3 , count:3}
{ min:5 , max:8 , count:4}
{ min:20 , max:21 , count:2}
Please, advice suitable solution , collection has ~100M docs , some of the values are in 10 digit ranges others in 15 digit ranges , but they are all sequentially incremental in their range?
Task 2:
Same think like in Task 1 , but taken based on custom sequence step ,
for example if the sequence step is 3:
{y:1}
{y:3}
{y:5}
{y:20}
{y:22}
need to produce:
{y:[1,5] ,count:3}
{y:[20,22]} , count:2}
Thanks!
P.S.
I succeeded partially to get some ranges picture by fetch distribution by number of digits range , but this seems to be very general:
db.collection.aggregate([
{
$addFields: {
range: {
$strLenCP: {
$toString: "$x"
}
}
}
},
{
$group: {
_id: "$range",
minValue: {
$min: "$x"
},
maxValue: {
$max: "$x"
},
Count: {
$sum: 1
}
}
},
{
$addFields: {
x: [
{
$toString: "$minValue"
},
{
$toString: "$maxValue"
}
]
}
},
{
$project: {
range: "$_id",
"_id": 0,
x: 1,
Count: 1
}
},
{
$sort: {
range: 1
}
}
])
playground
Here is another way of querying - produces result with format [ { min: 1 , max: 3 , count: 3 }, ... ]:
db.collection.aggregate([
{
$sort: { x: 1 }
},
{
$group: {
_id: null,
docs: { $push: "$x" },
firstVal: { $first: "$x" },
lastVal: { $last: "$x" }
}
},
{
$project: {
_id: 0,
output: {
$let: {
vars: {
result: {
$reduce: {
input: "$docs",
initialValue: {
prev: { $add: [ "$firstVal", -1 ] },
val: { min: "$firstVal", max: 0, count: 0 },
vals: [ ]
},
in: {
$cond: [
{ $eq: [ { $subtract: [ "$$this", "$$value.prev" ] }, 1 ] },
{
prev: "$$this",
val: {
min : "$$value.val.min",
max: "$$value.val.max",
count: { $add: [ "$$value.val.count", 1 ] }
},
vals: "$$value.vals"
},
{
vals: {
$concatArrays: [
"$$value.vals",
[ { min : "$$value.val.min", max: "$$value.prev", count: "$$value.val.count" } ]
]
},
val: { min: "$$this", max: "$lastVal", count: 1 },
prev: "$$this"
},
]
}
}
}
},
in: {
$concatArrays: [ "$$result.vals", [ "$$result.val" ] ]
}
}
}
}
},
])
Use $setWindowFields instead of $group all data
db.collection.aggregate([
{
$setWindowFields: {
partitionBy: "",
sortBy: { x: 1 },
output: {
c: {
$push: "$x",
window: {
range: [ -3, 0 ]
}
}
}
}
},
{
$set: {
"c": {
"$cond": {
"if": { "$gt": [ { "$size": "$c" }, 1 ] },
"then": 0,
"else": 1
}
}
}
},
{
$setWindowFields: {
partitionBy: "",
sortBy: { x: 1 },
output: {
g: {
$sum: "$c",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
},
{
$group: {
_id: "$g",
count: { $sum: 1 },
max: { "$max": "$x" },
min: { "$min": "$x" }
}
}
])
mongoplayground
In PostgreSQL
CREATE TABLE test (
id INT,
x INT
);
INSERT INTO test VALUES (1, 1);
INSERT INTO test VALUES (2, 3);
INSERT INTO test VALUES (3, 5);
INSERT INTO test VALUES (4, 20);
INSERT INTO test VALUES (5, 22);
SELECT
MAX(x) AS max, MIN(x) AS min, COUNT(*) AS count
FROM (
SELECT *, SUM(inc) OVER(ORDER BY x) AS grp
FROM (
SELECT *, CASE WHEN x - LAG(x) OVER(ORDER BY x) < 4 THEN NULL ELSE 1 END AS inc
FROM test
) q
) q
GROUP BY grp
db-fiddle
using $reduce
if i'm not mistaken for task2 just change 1 in $cond, $ne to any sequence step you want
playground
db.collection.aggregate([
{
"$sort": {
x: 1
}
},
{
$group: {
_id: null,
temp: {
$push: "$$ROOT"
}
}
},
{
"$project": {
_id: 0,
"temp_field": {
"$reduce": {
"input": "$temp",
"initialValue": {
"prev": -999999,
"min": -999999,
"count": 0,
"ranges": []
},
"in": {
"prev": "$$this.x",
"count": {
"$cond": [
{
$gt: [
{
"$subtract": [
"$$this.x",
"$$value.prev"
]
},
1//sequence step
],
},
1,
{
"$add": [
"$$value.count",
1
]
}
]
},
"min": {
"$cond": [
{
$gt: [
{
"$subtract": [
"$$this.x",
"$$value.prev"
]
},
1//sequence step
],
},
"$$this.x",
"$$value.min"
]
},
"ranges": {
"$concatArrays": [
"$$value.ranges",
{
"$cond": [
{
$gt: [
{
"$subtract": [
"$$this.x",
"$$value.prev"
]
},
1//sequence step
],
},
[
{
max: "$$value.prev",
min: "$$value.min",
count: "$$value.count"
}
],
[]
]
}
]
}
}
}
}
}
},
{
"$project": {
ranges: {
"$concatArrays": [
"$temp_field.ranges",
[
{
max: "$temp_field.prev",
min: "$temp_field.min",
count: "$temp_field.count"
}
]
]
}
}
}
])
and at the end pop the first element from array
Comment by R2D2 after testing in the real use case I hit the memory limit with allowDiskUse: true:
2022-02-14T09:38:27.575+0100 E QUERY [js] Error: command failed: {
"ok" : 0,
"errmsg" : "$push used too much memory and cannot spill to disk. Memory limit: 104857600 bytes",
"code" : 146,
"codeName" : "ExceededMemoryLimit",
Increased the memory to 2GB ( max allowed ) with:
db.adminCommand({setParameter:1 , internalQueryMaxPushBytes: 2048576000 })
But still faced the limit , then decided to split the collection to small ones so finally got my results , thank you once again!

How to transform an object into an array and removing the empty values?

I would like to transform an object in an array, removing the objects that have no values.
So I would like to create this new array of objects.
Object I am receving:
{
"61e048080589f874231c1a85": [
{
"xAxesListings": "61e048080589f874231c1a85",
"xAxesProducts": 0
},
{
"xAxesListings": "61e048080589f874231c1a85",
"xAxesProducts": 1
},
{
"xAxesListings": "61e048080589f874231c1a85",
"xAxesProducts": 2
}
],
"61f2f65190c83cffb800bda3": [
0,
0
],
"61f7000ea4f1662e206d5c0f": [
{
"xAxesListings": "61f7000ea4f1662e206d5c0f",
"xAxesProducts": 0
}
]
}
Expected output:
[
{ "xAxesListings": "61e048080589f874231c1a85", "xAxesProducts": 0},
{ "xAxesListings": "61e048080589f874231c1a85", "xAxesProducts": 1},
{ "xAxesListings": "61e048080589f874231c1a85", "xAxesProducts": 2}
{ "xAxesListings": "61f7000ea4f1662e206d5c0f", "xAxesProducts": 0}
]
what I have tried so far
var result = Object.keys(countRentals).map(function(e) {
return countRentals[e];
but i am getting this where I have a lot of values with zero that I don't need.
[
[
{
"xAxesListings": "61e045a8bd8e57666714c413",
"xAxesProducts": 0
}
],
{
"xAxesListings": "61e048080589f874231c1a85",
"xAxesProducts": 2
}
],
[
{
"xAxesListings": "61e1763538ee44ada3c955fb",
"xAxesProducts": 0
},
0
],
[
{
"xAxesListings": "61e1770138ee44ada3c95604",
"xAxesProducts": 0
},
0
],
[
0
],
[
0,
0
],
});
I also have tried this:
var arr = Object.entries(countRentals);
and in this case I am getting this:
[
[
"61e045a8bd8e57666714c413",
[
{
"xAxesListings": "61e045a8bd8e57666714c413",
"xAxesProducts": 0
}
]
],
[
"61e0474843bbc2ab0d553633",
[
{
"xAxesListings": "61e0474843bbc2ab0d553633",
"xAxesProducts": 0
}
]
],
One of the possible solutions could look as follows:
Object.values(yourStructure)
.flat()
.filter(v => typeof v === 'object');

Find another way to solve the problem (group an array of objects)?

I am solving the problem as follows:
I have an array of objects with input format:
let allTasks = [
{
time: "07-2020",
tasks: [
{
code: "p1",
value: 1111
}
],
},
{
time: "07-2020",
tasks: [
{
code: "p2",
value: 2222
}
]
},
{
time: "08-2020",
tasks: [
{
code: "p1",
value: 3333
}
]
},
{
time: "08-2020",
tasks: [
{
code: "p2",
value: 4444
}
]
},
{
time: "09-2020",
tasks: [
{
code: "p1",
value: 5555
}
]
},
{
time: "09-2020",
tasks: [
{
code: "p2",
value: 6666
}
]
},
]
I want to convert into a format that is formatted as follows:
output = [
{
p1: [
["07-2020",1111],
["08-2020",3333],
["09-2020",5555],
]
},
{
p2: [
["07-2020",2222],
["08-2020", 4444],
["09-2020", 6666],
]
},
// ... p3, p4....
]
I use reduce() method to group the objects in an array.
let newArr = [];
allTasks.forEach((x,index)=>{
newArr.push({
tasks: x.tasks.map(y=>Object.assign(y,{time: x.time}))
})
})
console.log('newArr',newArr);
let listTask = newArr.flatMap(x=>x.tasks);
let groupData = listTask.reduce((gr,item)=>{
gr[item.code] = [...gr[item.code] || [],item];
return gr;
},[])
let newGroupData = Object.entries(groupData).map(([key,data])=>{
console.log('-------------------------')
let result = Object.values(data.reduce((arr,item)=>{
arr[item.time] = arr[item.time] || [item.time];
arr[item.time].push(item.value);
return arr;
},[]));
return {
[key]: result
}
})
console.log('newGroupData',newGroupData)
The results have been expected as above. But my code is long, how do I refactor my code and is there a better way to do it ?
Please help me.
Thank you!
A different approach
You could flatten the tasks first, with complemented key-value pair of time. To array of this
[
...
{ code: 'p1', value: 1111, time: '07-2020' }
...
]
After that, group task by code and do some manipulation with the grouped to achieve your expected result
const groupByCode = {}
allTasks
.flatMap((parentTask) =>
parentTask.tasks.map((task) => ({ ...task, time: parentTask.time }))
)
.forEach((flattenedTask) => {
if (groupByCode[flattenedTask.code]) {
groupByCode[flattenedTask.code].push(flattenedTask)
} else {
groupByCode[flattenedTask.code] = [flattenedTask]
}
})
const res = Object.entries(groupByCode).map(([code, tasks]) => ({
[code]: tasks.map((task) => [task.time, task.value]),
}))
Full implementation
let allTasks = [
{
time: "07-2020",
tasks: [
{
code: "p1",
value: 1111,
},
],
},
{
time: "07-2020",
tasks: [
{
code: "p2",
value: 2222,
},
],
},
{
time: "08-2020",
tasks: [
{
code: "p1",
value: 3333,
},
],
},
{
time: "08-2020",
tasks: [
{
code: "p2",
value: 4444,
},
],
},
{
time: "09-2020",
tasks: [
{
code: "p1",
value: 5555,
},
],
},
{
time: "09-2020",
tasks: [
{
code: "p2",
value: 6666,
},
],
},
]
const groupByCode = {}
allTasks
.flatMap((parentTask) =>
parentTask.tasks.map((task) => ({ ...task, time: parentTask.time }))
)
.forEach((flattenedTask) => {
if (groupByCode[flattenedTask.code]) {
groupByCode[flattenedTask.code].push(flattenedTask)
} else {
groupByCode[flattenedTask.code] = [flattenedTask]
}
})
const res = Object.entries(groupByCode).map(([code, tasks]) => ({
[code]: tasks.map((task) => [task.time, task.value]),
}))
console.log(JSON.stringify(res, null, 2))
Reference
Array.prototype.flatMap()
Object.entries()

Need help extracting objects from deep arrays and combining into one single array

What's the best way to extract the objects with the target properties and combine them into one array?
app.js
const p1 = [[{ target1: 3 }, { target2: 1 }], [{ t: 2 }]];
const p2 = [[{ target1: 1 }, { target2: 2 }], [{ t: 2 }]];
const p3 = [[{ target1: 4 }, { target2: 1 }], [{ t: 2 }]];
const p4 = [[{ target1: 2 }, { target2: 2 }], [{ t: 2 }]];
Promise.all([p1, p2, p3, p4]).then((values) => {
console.log(values);
// Some way to extract the objects that have the target property in them
// and combine them into a single array
});
results
[ [ [ [Object], [Object] ], [ [Object] ] ],
[ [ [Object], [Object] ], [ [Object] ] ],
[ [ [Object], [Object] ], [ [Object] ] ],
[ [ [Object], [Object] ], [ [Object] ] ] ]
desired
[{ target1: 3 }, { target2: 1 },
{ target1: 1 }, { target2: 2 },
{ target1: 4 }, { target2: 1 },
{ target1: 2 }, { target2: 2 }]
You can achieve your goal with the code below.
const p1 = [[{ target1: 3 }, { target2: 1 }], [{ t: 2 }]];
const p2 = [[{ target1: 1 }, { target2: 2 }], [{ t: 2 }]];
const p3 = [[{ target1: 4 }, { target2: 1 }], [{ t: 2 }]];
const p4 = [[{ target1: 2 }, { target2: 2 }], [{ t: 2 }]];
Promise.all([p1, p2, p3, p4]).then((values) => {
const [a1, a2, a3, a4] = values
const [t1] = a1;
const [t2] = a2;
const [t3] = a3;
const [t4] = a4;
const result = [...t1, ...t2, ...t3, ...t4];
console.log(result);
});
Try mapping over the array and using deconstruction:
let transformedValues = Array.prototype.concat( //poor man's one level flatten when combined with ...
...values.map(([[target1, target2]])=> [target1, target2])
)
I'm assuming the number of p values varies, but the structure of the p values is constant.

Categories