kotlin - Is there a way to merge two lists? - list

val current = listOf(
Item(0, "url_0", "content_0"),
Item(1, "url_1", "content_1"),
Item(2, "url_2", "content_2"),
Item(3, "url_3", "content_3"),
Item(4, "url_4", "content_4"),
Item(5, "url_5", "content_5")
)
val contentModify = listOf(
Item(0, "url_0", "content_0"),
Item(1, "url_1", "content_1"),
Item(2, "url_2", "content_20"), // modify
Item(3, "url_3", "content_30"), // modify
Item(4, "url_4", "content_40"), // modify
Item(5, "url_5", "content_5")
)
val urlModify = listOf(
Item(0, "url_0", "content_0"),
Item(1, "url_1", "content_1"),
Item(2, "url_2", "content_2"),
Item(3, "url_3", "content_3"),
Item(4, "url_40", "content_4"), // modify
Item(5, "url_50", "content_5") // modify
)
val content = current.filterNot(contentModify::contains)
val url = current.filterNot(urlModify::contains)
I made [content], [url] to find the changed points by comparing [contentModify] and [urlModify] modified in different places with [current] .
I want to combine the two results to make one edit list, but I am wondering if there is a way to merge them if the Id values ​​are the same.
Is there a way to combine these two results in kotlin??

I don't understand what elements the final list should contain...
If you want a list of all items that are changed (but with the old values) the simple way is to use a set: (url + content).toSet()
This instruction produces a set that contains the following items:
Item(2, "url_2", "content_2")
Item(3, "url_3", "content_3")
Item(4, "url_4", "content_4")
Item(5, "url_5", "content_5")
but this list doesn't contain the updated data, so I suppose that you want the following list:
Item(2, "url_2", "content_20")
Item(3, "url_3", "content_30")
Item(4, "url_40", "content_40")
Item(5, "url_50", "content_5")
For this there isn't any built-in function so you should implement something like:
// your version of content and url are sublists of current but
// you need the updated items (from contentModify and urlModify)
val content = contentModify.filterNot(current::contains)
val url = urlModify.filterNot(current::contains)
val mergedList = (content + url)
.groupBy{it.id}
.values
.flatMap{ items ->
sequenceOf(if(items.size == 2){Item(items[0].id, items[0].content, items[1].url)} else {items.first()})
}

Related

How to "remove all duplicates and original of duplicate" from a list of objects in Java 8?

I got two:
registryId:1
registryID:1
registryID:2
The final list should be: I mean remove 1 compeletly
registryID:2
I got this solution:
List<TerpAccountListV> terpAccountListVFinal = compareUpdate(terpAccountListV, xxedgeAccountsListV);
Set<TerpAccountListV> set = terpAccountListVFinal.stream()
.collect(Collectors.toCollection(() -> new TreeSet()<>(Comparator.comparing(TerpAccountListV::getRegistryId))));
But this will make a Single Set having registry ID.
How will i remove element from above List using this set in Java 8?
First, count the occurrence by RegistryId in list. Then create a set of a non-duplicate items' RegistryId
Set<Integer> set =
list.stream()
.collect(Collectors.groupingBy(TerpAccountListV::getRegistryId,
Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1L)
.map(e -> e.getKey())
.collect(Collector.toSet());
Then filter the list if RegistryId contains in set
List<TerpAccountListV> res = list.stream()
.filter(e -> set.contains(e.getRegistryId()))
.collect(Collector.toList());
Update:
You can do set creation part this way also
Set<Integer> track = new HashSet<>();
Set<Integer> set = new HashSet<>();
for (Integer item : list) {
if(!track.add(item.getRegistryId())) {
set.remove(item.getRegistryId());
} else {
set.add(item.getRegistryId());
}
}

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.

How to filter query result to list of strings

I have a query result same as below:
var ptns = from p in db.Patients
select p;
This query returns a list of patients, but I need to filter the result based on DoctorNameID. The DoctorNameID should be in list of doctors as below:
List<string> listofDoctors = usrtodrs.Split(',').ToList();
I have searched a lot but I don't know how to do this. I have tested this query which doesn't work:
var ptns1 = from d in listofDoctors
join p in ptns.ToList() on d equals p.DoctorNameID
select p;
And also this query:
var ptns1 = ptns.ToList()
.Where(a => listofDoctors.Equals(a.DoctorNameID))
.ToList();
Any help?
You can use Contains extension and get the desired result.
var ptns1 = ptns.Where(x => listofDoctors.Contains(x.DoctorNameID)).ToList();
Refer the C# Fiddle with sample data.

Check items from a List of ValueTuple and return results in another List of ValueTuple C#7

Please consider the following list of ValueTuple C#7
static void Main(string[] args)
{
List<(double prices, int matches)> myList = new List<(double, int)>();
myList.Add((100, 10));
myList.Add((100.50 , 12));
myList.Add((101 , 14));
myList.Add((101.50 , 16));
}
What would be a simple way to search for items meeting conditions for "prices" AND "matches" within the List and return the results in another List of ValueTuple.
For instance if I want to return another List of ValueTuples meeting "prices > 101 and matches > 6"
Can you post an example please?
It's easier if you give names to the items :
var myList = new List<(double d,int i)>
{
(100, 10),
(100.50 , 12),
(101 , 14),
(101.50 , 16)
};
var results = myList.Where(x => x.d>101 && x.i>6);
Without the names you'd have to write
var results = myList.Where(x => x.Item1>101 && x.Item2>6);
C# 7.3 added tuple equality but not comparison. You can now write :
var result = myList.Where(d=>d == (101,14));
and
var result = myList.Where(d=>d != (101,14));
But not
var result = myList.Where(d=>d > (101,14));

Add a dynamic key to an anonymous List

How can I add a dynamic key to an anonymous List such as the mydatetime below:
DateTime myDateTime = DateTime.Parse(datepickerval, ukCulture.DateTimeFormat);
var qid = (from p in db.Vw_INTERACTPEOPLE
select p
);
var AvilList = new List<object>();
var ddate = myDateTime.DayOfWeek.ToString().Substring(0, 3) + "Jul" + myDateTime.Day;
foreach (var q in qid)
{
AvilList.Add(
new
{// Availability
Name = q.Fullname,
here >>> ddate = "Some Test"
});
As adam says above there is no way to do this using Lists, however since the Slickgrid is expecting a Json return, I simply built the string in .net then returned it via the JavaScriptSerializer serializer, then in the code behind simply used eval to de-serialize back into an array.