I have an array similar to this:
[
{part_number: 1, station: 300, description: "cable", qty: 40},
{part_number: 1, station: 40, description: "cable", qty: 20},
{part_number: 2, station: 300, description: "monitor", qty: 12},
{part_number: 3, station: 40, description: "mounting bracket", qty: 33},
]
I am displaying the items with ngRepeat and filtering for unique part number. For each part_number listed, I need to find the qty of each part at the multiple stations and display it in the qty field of that line.
For example:
Part 1 has a total qty of 60, 40 at station 300 and 20 at station 40. Part 2 has a total qty of 12 at station 300. Part 3 has a total qty of 33 at station 40.
I am not sure how to get these quantities or how to display them properly by part number. Any help would be appreciated.
EDIT(1):
Sorry to make this so vague which makes it look like I haven't even tried. I have been looking at higher order functions, but cannot determine which ones I should use in conjunction to achieve this end.
Would it be possible to use .map to add a "qty" key/value pair to each object in the array...then simply add an expression in my view to show this value?
I need to get the accumulated quantity of the duplicated parts before I set this value in the uniquely filtered array.
You need to loop through your array and calculate sum. You can try the following
html
<div ng-repeat="item in result">
{{item.description}}({{item.part_number}}) - {{item.qty}}
</div>
js
$scope.data = [
{part_number: 1, station: 300, description: "cable", qty: 40},
{part_number: 1, station: 40, description: "cable", qty: 20},
{part_number: 2, station: 300, description: "monitor", qty: 12},
{part_number: 3, station: 40, description: "mounting bracket", qty: 33}
];
$scope.result = [];
$scope.data.reduce(getSum, {});
function getSum(result, item) {
if (!result[item.part_number]) {
result[item.part_number] = { part_number: item.part_number, qty: 0 ,description: item.description};
$scope.result.push(result[item.part_number])
}
result[item.part_number].qty += item.qty;
return result;
}
Demo
Related
First of all sorry if the title does not reflect what I really need to do.
Imagine a collection that represents what products sell which vendor. Let´s simplify like:
{_id, productID, VendorID, Price, Stock}
For example, we could have:
{_id: 1 ,productID: 1, vendorID: A, price: 0, stock: 0},
{_id: 2 ,productID: 2, vendorID: A, price: 0, stock: 0},
{_id: 3 ,productID: 3, vendorID: A, price: 0, stock: 0},
{_id: 4 ,productID: 4, vendorID: A, price: 0, stock: 0},
{_id: 5 ,productID: 1, vendorID: B, price: 0, stock: 19},
{_id: 6 ,productID: 3, vendorID: B, price: 0, stock: 21}
The idea is that Vendor A is the Super Admin and the one who controls which products can be sold in the marketplace. That´s why all products sold by A have price = 0 and stock = 0.
What I am trying to get within the same query is. When Vendor B is logged:
List all the items that A is selling.
But if a product is sold by B, then I should return it instead of the A-one.
The result would look like:
{_id: 2 ,productID: 2, vendorID: A, price: 0, stock: 0},
{_id: 4 ,productID: 4, vendorID: A, price: 0, stock: 0},
{_id: 5 ,productID: 1, vendorID: B, price: 0, stock: 19},
{_id: 6 ,productID: 3, vendorID: B, price: 0, stock: 21}
Do you have any idea how I can do it in a shot?
I can do the filter in the frontend but I would prefer doing like this in order to avoid problems with pagination for example.
If you are sure that all products sold by A always have price = 0 and stock = 0, you can do the following trick:
db.collection.aggregate({
$match: {
vendorID: {
$in: [
"A",
"B"
]
}
}
},
{
$sort: {
productID: 1,
price: -1
}
},
{
"$group": {
"_id": "$productID",
"product": {
$first: "$$ROOT"
}
}
})
Mongo playground
by $match you are looking for all products owned by default vendor (A) and target vendor (B).
by $sort you group products by productID and by price in each group, so product sold by A will be last one in each group
by $group you extract product from each group
using $first it will be first product (with higher price, so product sold by A will be matched only if no other products with same ID were sold).
DB documents will be aggregated by $$ROOT into product field, so you can map them using:
// (javascript)
const productDocuments = aggregationResult.map(row => row.product);
Notice: product sold by A still can be extracted even if B sold product with same ID in cases when B's product also have price = 0.
I receive an array of product objects like such from my backend.
products = [
{id: 1, price: 10, category: "food", name: "apples"},
{id: 2, price: 5, category: "supplies", name: "spoons"},
{id: 3, price: 15, category: "pets", name: "cat treats"},
{id: 4, price: 9, category: "food", name: "oranges"},
// ...
]
I am looking to render all my products as strips based on their category in a specific order of priority (similar to how Netflix aligns their shows). I don't want them displayed in random order, such as the category strip of food being at the top, the next category strip being pets, etc.
I currently decided to create a map object since it keeps order as followed:
let filteredProducts = new Map([
["food", []],
["pets", []],
["supplies", []],
// ...
])
for (let product of products) {
let category = product["category"]
filteredProducts.get(category).push(product)
}
The goal is to then iterate through the map object and return multiple React Component of category strips from top to bottom.
My question is, I can't help but feel that there are more efficient ways to render this as I don't see map objects being utilized commonly. Are there more efficient and frequently used ways to filter and render by priority or is this in the right direction?
I do believe there is more easier way to do this using Array sort function.
Please consider the snippet below.
const products = [
{id: 1, price: 10, category: "food", name: "apples"},
{id: 2, price: 5, category: "supplies", name: "spoons"},
{id: 3, price: 15, category: "pets", name: "cat treats"},
{id: 4, price: 9, category: "food", name: "oranges"},
// ...
]
const priority = [
'food',
'supplies',
'pets'
]
const orderedProducts = products.sort(
(p1, p2) => priority.indexOf(p1.category) - priority.indexOf(p2.category)
);
Let me know if this looks much cleaner & easier approach.
I have an array of objects like this:
$scope.sortableItems =
[
{
name: 'Blue Shirt',
fields: {Price: 20}
},
{
name: 'Pink Shirt',
fields: {Price: 80},
},
{
name: 'Orange Shirt',
fields: {Price: 10},
}
]
I need to make an ng-repeat field that can sort the products based on price from low to high or high to low.
I tried this:
.product(ng-repeat="item in sortableItems | orderBy:fields.Price")
But it had no effect.
Additionally I have another variable $scope.sortFunction which can equal Price: Low-High or Price: High-Low the end result needs to detect the value of $scope.sortFunction and sort based on the value of the string. Not sure how to do that with an ng-repeat
You can create a function that would return price and use that function inside your orderBy
js
$scope.getPrice = function(item){
return item.fields['Price'];
}
html
<div ng-repeat="item in sortableItems | orderBy:getPrice:false">{{item.fields['Price']}}</div>
order by takes a second boolean value that you can use for asc / desc ordering.
Demo
I have a problem with SOLR Collapse I cannot move with.
Assuming documents
{ id: 1, parent_id: x, value: 3 },
{ id: 2, parent_id: y, value: 5 },
{ id: 3, parent_id: x, value: 7 },
{ id: 4, parent_id: y, value: 10 }
now let's say I want to collapse on parent_id and minimum value doc:
{!collapse field=parent_id min=value }
what I get from SOLR is expected:
GROUP x: { id: 1, parent_id: x, value: 3 },
GROUP y: { id: 2, parent_id: y, value: 5 }
but let's say I want to get results where minimum value is 4, so I apply a filter.
{!collapse field=parent_id min=value } {value:[4 TO *]}
What I get is understandable but not exactly what I want:
GROUP x: { id: 3, parent_id: x, value: 7 },
GROUP y: { id: 2, parent_id: y, value: 5 }
So the results are filtered then collapsed on the parent_id and minimum value is selected but what I really want is to get only those groups which MINIMUM value is within the range:
GROUP y: { id: 2, parent_id: y, value: 5 }
GROUP x is not in result as minimum value is 3
If I understand correctly from docs - collapsing happens after the request but is there any way how to retrieve what I am trying?
Thanks a lot
as you said, the other query is run first, then collapse post filter runs.
I would try this with Streaming Expressions, you should be able to:
group by parent_id
take min of value
filter the tuples whose value > your range
Take a look at the things you can do in the page above
I have an array of objects with unique IDs:
[{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}, ...]
I also have an array of User records with matching IDs. The user records have "name" but not "score":
[{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}, ...]
How can I create a single array with each id, name, and score?
[{id: 1, name: "Jon", score: 33}, {id: 23, name: "Tom", score: 50}, {id: 512, name: "Joey", score: 27}, ...]
I tried merge, combine, filter, etc but haven't found the Ruby function to accomplish this.
Assuming that in users there is always record with corresponding :id from scores:
scores = [{id: 1, score: 33}, {id: 23, score: 50}, {id:512, score: 27}]
users = [{id: 1, name: "Jon"}, {id: 23, name: "Tom"}, {id: 512, name: "Joey"}]
scores = scores.map { |score| score.merge(users.find { |user| user[:id] == score[:id] }) }
# => [{:id=>1, :score=>33, :name=>"Jon"}, {:id=>23, :score=>50, :name=>"Tom"}, {:id=>512, :score=>27, :name=>"Joey"}]
Hope that puts you in proper direction!
You can use an intermediate Hash.
hsh = Hash[ a1.map {|h| [h[:id], h[:score]]} ]
# => {1=>33, 23=>50, 512=>27}
a2.map {|h| h[:score] = hsh[h[:id]]; h}
# => [{:id=>1, :name=>"Jon", :score=>33}, {:id=>23, :name=>"Tom", :score=>50}, {:id=>512, :name=>"Joey", :score=>27}]
If, as in the example, scores[i][:id] = users[i][:id] for all i, and you are using v1.9+ (where key insertion order is maintained), you could write:
scores.zip(users).each_with_object({}) do |(sh,uh),h|
h.update(sh).update(uh)
end
Would I use this? Would you?