How to find sum of a field in nested lists with a where condition? - list

I am having two lists and I need to find sum of nested list and there should be filter on the first list.
Ex:
Class Customer{
string Name
List<Order> Orders
string State
}
Class Order{
int OrderID
int OrderTotal
int ItemCode
}
I need to find sum of Orders in a particular state, I am looking for a lambda expression for this.

Below is the lambda expression with can be used to get the sum of the orderTotal with the filter on state.
Customer customer = new Customer();
Now add some data to your customer object and Order object.
customer.Where(cust => cust.State.Equals("Alaska")).Sum(order => order.OrderTotal);

Related

Kotlin aggregation function

I need to write somehow a function, that aggregates results in a list.
I'm working with an Order dto (java class)
public class Order {
private Long orderId;
private String description;
...
}
I have two APIs, the one that return orders and the other one that returns suborders. So i retrieve all orders and get all suborders in a loop by predefined ids:
// for example i have a predefined list of order id's
List<Long> orderIds = listOf(1L, 2L, 3L, 4L, 5L)
val allOrders = orderIds.map {
// at first i retrieve an order
val order = orderService.getOrderById(it.orderId)
// then i get a list of suborders
val suborders = suborderService.getSubordersByOrderId(it.orderId)
// ?
}
How can i combine order (Order) and suborders (List) to a list of Order and then all the elements of nested list into a single list?
I think flatMap is what you want:
val allOrders: List<Order> = orderIds.flatMap {
val order = orderService.getOrderById(it)
val suborders = suborderService.getSubordersByOrderId(it)
suborders + order
}
It flatten all the items of the returned list into one single list altogether.

Group by, sum then sort a list of transaction objects java

I have a list of transactions by day, the transaction contains the following attributes:
Transaction(int transactionID,
DateTime transactionDate,
String shopId,
int productReference,
int quantity,
float price);
Having a list List<Transaction>, I want to extract top 100 selled products by shop.
So I need to group transactions by shopId then by productReference, then summing quantities than sorting from most selled to least.
Thanks you for your Help
private static Collector<Transaction, ?, List<Transaction>> limit(int limit) {
return Collector.of(
ArrayList::new,
(list, transaction) -> { if (list.size() < limit) list.add(transaction); },
(list1, list2) -> {
list1.addAll(list2.subList(0, Math.min(list2.size(), Math.max(0, limit - list1.size()))));
return list1;
}
);
}
public static void main(String[] args) {
Map<String, List<Transaction>> groupedMap = listOfTransactions
.stream()
.sorted((t1, t2) -> Integer.compare(t2.getQuantity(), t1.getQuantity()))
.collect(
Collectors.groupingBy(
Transaction::getShopId,
limit(100)
)
);
}
As a result you'll get a map with shopId as a key, and lists of transactions sorted by quantity as a value.
Is it expected behavior?
I'd suggest using of additional Product type, with overridden equals() and hasCode() which will consist only of shopId and productReference . New type will serve as an output, which will make all the transformation job more obvious. Consider my version, with Lombok lib usage:
import lombok.*;
#Data
#RequiredArgsConstructor(staticName = "of")
#ToString
public class Product {
final String shopId;
final int productReference;
}
and the function code itself:
List<Product> products = transactions.stream()
// grouping transactions by the same product
.collect(Collectors.groupingBy(transaction -> Product.of(
transaction.getShopId(),
transaction.getProductReference())))
.entrySet().stream()
// summing all price * quantity occurrences to find top sellings
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().stream()
.mapToDouble(p -> p.getQuantity() * p.getPrice())
.sum()))
.entrySet().stream()
// sorting by the most expensive ones at the top,
// limiting to 10 and collecting to the list
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.map(Map.Entry::getKey)
.limit(10)
.collect(Collectors.toList());

What is the meaning of the input variables when registering a new group?

The (smart) contract function to register a new group looks as follows:
async registerGroup(name, members, min, max, m, updateInterval) {
...
}
What is the meaning of min,max, m and updateInterval in the above?
name is the name of the group
members is the list of member added to the group at initialization. The list contains probably the public keys.
min and max set the minimum and maximum number of members, min should be >= 3.
m that is the minimum vote weight a request transaction must get.
m sets the total weight of votes required to activate a group transaction the group, the check can be found in the asch/src/contract/group.js file in the activate() function:
const group = await app.sdb.load('Group', account.name)
if (totalWeight < group.m) return 'Vote weight not enough'
Notice that m also can be set when adding a new group member with group.addMember:
async addMember(address, weight, m) {
...
if (m) {
const group = await app.sdb.load('Group', this.sender.name)
if (!group) return 'Group not found'
group.m = m
app.sdb.update('Group', { m }, { name: this.sender.name })
}
...
}
The updateInterval is unclear till now. Possible related to the time a group member should lock it's XAS.

How to search in an List and my List is look like : List<Object> myList = new ArrayList<Object>() [duplicate]

This question already has answers here:
How to filter a Java Collection (based on predicate)?
(29 answers)
Closed 6 years ago.
I want to search in a List and my List is look like
List<Employee> oneEmp= new ArrayList<Employee>();
List<Employee> twoEmp= new ArrayList<Employee>();
oneEmp= [Employee [eid=1001, eName=Sam Smith, eAddress=Bangluru, eSalary=10000000], Employee [eid=0, eName=, eAddress=, eSalary=null], Employee [eid=1003, eName=Amt Lime, eAddress=G Bhagyoday, eSalary=200000], Employee [eid=1004, eName=Ash Wake, eAddress=BMC, eSalary=200000], Employee [eid=1005, eName=Will Smith, eAddress= Delhi, eSalary=200000], Employee [eid=1006, eName=Shya Ymwar, eAddress=Madras, eSalary=50000], Employee [eid=1007, eName=Nag Gam, eAddress=Pune, eSalary=10000000], Employee [eid=1008, eName=Arti, eAddress=Delhi, eSalary=10000000]]
twoEmp= [Employee [eid=0, eName=null, eAddress=null, eSalary=100000], Employee [eid=0, eName=null, eAddress=null, eSalary=50000], Employee [eid=0, eName=null, eAddress=null, eSalary=200000]]
I am using code like this:-
for(Employee two : twoEmp){
for (Iterator<Employee> iterator = oneEmp.iterator(); iterator.hasNext(); ) {
Employee e = iterator.next();
if (e.geteSalary() != null && two.geteSalary() != null && e.geteSalary().compareTo(two.geteSalary()) == 0) {
finalEmpList.add(e);
}
}
}
But this still required 2 for loop
I am using JAVA 1.6
My Employee class has attributes:
//Employee class
int eid;
BigInteger eSalary;
String eName, eAddress;
Now I want to get all the objects in List who's Salary = 10000000
result should be :
[Employee [eid=1001, eName=Sam Smith, eAddress=Bangluru, eSalary=10000000], Employee [eid=1007, eName=Nag Gam, eAddress=Pune, eSalary=10000000], Employee [eid=1008, eName=Arti, eAddress=Delhi, eSalary=10000000],.........................]
I would like to achieve this without using any loop or minimum loop required because data will be large
Yes, it is possible to avoid the loop using streams.
First, consider using a generic collection:
List<Employee> employees = new ArrayList<>():
//add all employees to the list
Now you can use streams to filter your list
List<Employee> filtered = employees.stream()
.filter(emp -> emp.getSalary() == 10000000)
.collect(Collectors.toList());
Edit: Probably Stream library is still using some kind of loop internally but while its implementation is hidden from me I do not worry.
A List is a sequential container, to do any kind of filtering on a list, your only option is to iterate over it.
For the query you mentioned,you can use the Map data structure with a BigInteger type for the key (representing the salary) and a List<Employee> for the mapped value type. This will enable you to look for all the employees that earn a certain salary in constant time without having to iterate over the whole list.
Unfortunately though, this solution can't help you do any other queries like "how many employees earn more than 60000", to preform all types of queries on a large data set you should use a database.
PS: You don't need to use the BigInteger type for the salary, unless you think someone earns more than 2,147,483,647
Something like this should do the trick; iterate over the List, and remove the items which you don't want, leaving only the ones which you do want.
List myList = new ArrayList(); //... add items
[...]
for (Iterator<Employee> iterator = myList.iterator(); iterator.hasNext(); ) {
Employee e = iterator.next();
if (e.getSalary() != 10000000) {
iterator.remove();
}
}
//your list now contains only employees whose salary = 10000000
Edit: And no, you cannot do this without a loop. In order to do this kind of thing, you have to iterate over your Collection using a loop. Even if you use a library or the Java Streams API to do this, it will still use a loop of some sort under the hood. However, this will be quite efficient, even with as large dataset. (How large ? Why do you want to avoid using a loop ?)

What is the difference between a list of tuples and a list of objects?

Please see I want list employee objects. So I have below two options.
List<Tuple<int, string, string, string>>
List<Employee>where Employee is class contains 4 properties.
My doubt is what should I use(tuple or list of employee object?
If it is List<Employee> then in which scenario I should use List<Tuple<int, string, ...>>.
You should not use tuples unless you are doing some sort of arithmetic operation where tuple would be an acceptable and widely understood method of supplying values. Tuples make it a maintenance nightmare for anyone who is not familiar with your process as you built it.
Edit: Think about the difference between seeing:
var employeeList = DAL.getEmployees();
var activeEmployees = employeeList.Where(employee => employee.IsActive);
vs
var employeeTuple = DAL.getEmployees();
var activeEmployees = employeeTuple.Where(employee => employee.Item3);
In the second example, I know THAT you created an active employee list, but I don't know HOW you did it.
That's rather obvious. If you already have the Employee class then using List<Employee> is straightforward:
List<Employee> list = new List<Employee>();
list.Add( e );
...
Employee e = list.Where( i => i.Name == "John" ).FirstOrDefault();
whereas using List<Tuple<...>> is at least cumbersome:
List<Tuple<....>> list = new List<Tuple<....>>();
list.Add( new Tuple<...>( e.Name, e.Surname, e.Whateverelse, e.YetAnother ) );
...
// retrieve the tuple
var tuple = list.Where( i => i.Item1 == "John" );
// make Employee out of it
Employee e = new Employee( e.Item1, e.Item2, e.Item3, e.Item4 );