Convert List<Class> to List<Class.property> - list

I am looking for an elegant way to convert a List where we remove the object information and keep only a specific property.
example: List< Fruit> becomes List with the property fruitColor (a String) kept.

I think you're looking for:
var listOfFruit = ...;
var listOfColors = listOfFruit.map((e) => e.fruitColor).toList();

Related

Gson deserialize Array of Integers in kotlin

Normally, when I deserialize a json-String I use something like this:
val result = gson.fromJson<myObject>(json, object : TypeToken<myObject>() {}.type)
But now I want to deserialize a simple List of Int and I cannot build an object for that.
The json-String is extremely simple and looks like this:
[1,35,37,255]
and I would like to save it into a List but
val result = gson.fromJson<List<Int>>(json, object : TypeToken<List<Int>>() {}.type)
does not work because there is no object. How should I handle such an easy structure? Is it better without gson eg with explode?
I think you in kotlin you don't need to use TypeToken you can go like
val result = gson.fromJson<List<Int>>(json)
here if you want to read more
val gson = Gson()
val itemType = object : TypeToken<List<Item>>() {}.type
itemList = gson.fromJson<List<Item>>(itemListJsonString, itemType)

More idiomatic way to initialize this kotlin list?

I want to have an immutable list, since I don't really need the mutability so it likely to just cause bugs. However, the list is a lateinit var declared at the class level.
I want to initially populate the list with values from a loop somewhat like this:
for (items in someOtherCollection) {
val itemToAdd = doSomeProcessingOnThisData()
list.add(itemToAdd)
}
However, since the list is immutable, I can't call add(). Is there a better way to init a list such as this without simply adding all the values to a second, mutable list and then assigning it to an immutable list?
My current solution is this, but it just seems inefficient:
val tmpList = mutableListOf<Data>()
foos.forEach() {
val itemToAdd = doSomeProcessing()
foos.add(itemToAdd)
}
this.list = tmpList
If you want to make a new list processing some data in another collection, try this:
this.list = someOtherCollection.map {
doSomeProcessing()
}
Give this a read for a better understanding: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html

Dropwizard /Jersey: Pass query-parameter with multiple values as List (maybe using a filter)

I have clients passing in IDs like this: /v1/path?id=1,2,3
What I have and want
I have a resource class for Dropwizard/Jersey.
I'd like to show up the query-parameter id=1,2,3 as a List parameter in my resource's GET method
// Resource class
public List<Something> getFilteredList(#QueryParam("id") List<String> ids) {
// filter the List<Something> based on a list of ids
}
Right now, the ids list contains 1 string which is "1,2,3".
What I tried
I tried a filter but the query parameters given by Jersey's
ContainerRequestContext.getUriInfo().getQueryParameters()
is immutable.
Questions
I would like to apply a filter and change any comma separated query parameters into multi-valued parameters so that the resource method gets a list instead.
Is there a way to change the existing query parameters using a Jersey filter?
What's a good way to solve this problem?
The best way I can think of is to just create a wrapper class for the list. This makes it easier to take advantage of the specified functionality of Jersey. You can see what I mean at Passing custom type query parameter.
For example
public class IdFilter {
private List<String> ids = new ArrayList<>();
public List<String> getIds() { return ids; }
public static IdFilter valueOf(String param) {
IdFilter filter = new IdFilter();
for (String id: param.split(",") {
filter.getIds().add(id);
}
}
}
getFilteredList(#QueryParam("id") IdFilter ids) {
We don't need to do anything else. Just having the static valueOf is enough for Jersey to know how to parse the query string.
3 ways to solve it:
use the generic context-parameter UriInfo , which is not very expressive
add an explicit custom type that can parse a comma-separated list
stay with #QueryParam List<String> requiring a concatenated query like ?id=1&id=2&id=3 given as URI
I would prefer the second as most-expressive, like answered already by Paul. This way you can concisely pass a single CSV like ?id=1,2,3,3 and also use a Set to ensure unique ID values, e.g. resulting in only [1, 2, 3].
Generic context-param UriInfo
One way would be to use a generic parameter #Context UriInfo to get the list in the method's body:
public List<Something> getFilteredList( #Context UriInfo uriInfo ) {
List<String> idList = uriInfo.getQueryParameters().get("id"); // before was #QueryParam("id")
System.out.println("idList: " + idList);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> idList.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See the tutorial in Java Vogue(2015): QueryParam Annotation In Jersey -
Custom type with static valueOf(String) factory-method
The other way is to design a custom type which can be constructed using a String:
class IdSet {
Set<String> values;
// a factory method, can also be named valueOf
public static IdSet fromString(String commaSeparated) {
return new HashSet( Arrays.asList( commaSeparated.split(",") ) );
}
}
public List<Something> getFilteredList(#QueryParam("id") IdSet ids) {
System.out.println("ids (Set): " + ids.values);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> ids.values.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See Jersey's JavaDocs for #QueryParam:
The type T of the annotated parameter, field or property must either:
Be a primitive type
Have a constructor that accepts a single String argument
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String))
Have a registered implementation of ParamConverterProvider that returns a ParamConverter instance capable of a "from string" conversion for the type.
Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2, 3 or 4 above. The resulting collection is read-only.
Use a collection interface with multiple key-value pairs
When the calling client uses following URI pattern: /something?id=1&id=2&id=3 then JAX-RS can deserialize them to a single parameter of List<String> id having given multiple elements:
public List<Something> getFilteredList(#QueryParam("id") List<String> ids) {
System.out.println("ids : "+ids);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> ids.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See Mkyong: JAX-RS #QueryParam example where explained the multiple occurrences of orderBy in the GET query:
#QueryParam will convert the query parameter “orderBy=age&orderBy=name” into java.util.List automatically.
See also
Handling Multiple Query Parameters in Jersey
Deserializing List<Map<String, String>> QueryParam in jersey 1
Jersey, #QueryParam List<String>

Combining lists into an arraylist (C#)

I have a list and I want to copy three other lists into it.
// The main list
List<List<string>> list= new List<List<string>>();
// The lists which I want to combine
ArrayList sublist1= new ArrayList();;
ArrayList sublist2= new ArrayList();;
ArrayList sublist3= new ArrayList();;
What I tried is:
list[0].AddRange(sublist1);
list[0].AddRange(sublist2);
list[0].AddRange(sublist3);
It doesn't work because It is multidimensional list. I need this type of list for the future plans.
How can I accomplist it?
As already mentioned in comments just use List<string> instead of ArrayList.
It has nothing to do about multidimensional arrays, just types mismatch.
Then you say List<List<string>> it basically means create list type, which will contain List<string> as items (the part in angle brackets), so you need to add them, not ArrayLists. Similarly List<string> means type of list which will contain string as items.
As in the comments, you need to pass a type that follows IEnumerable. For example, you can change your ArrayLists to List
// The main list
List<List<string>> list = new List<List<string>>();
// The lists which I want to combine
var sublist1 = new List<string>();
var sublist2 = new List<string>();
var sublist3 = new List<string>();
list[0].AddRange(sublist1);
list[0].AddRange(sublist2);
list[0].AddRange(sublist3);
change type of sublists to some IEnumerable<string> (string[] or List<string> or something else)
var sublist1 = new string[] {};
var sublist2 = new string[] {};
var sublist3 = new string[] {};
OR do cast
list[0].AddRange((IEnumerable<string>) sublist1);
list[0].AddRange((IEnumerable<string>) sublist2);
list[0].AddRange((IEnumerable<string>) sublist3);
Because you are trying to use AddRange method of System.Collections.Generic.List<T>
and the signature of this method is
public void AddRange(System.Collections.Generic.IEnumerable<T> collection)
so it requires IEnumerable as a parameter.

How do I find the piece of this text string in javascript?

I'm using jQuery and have retrieved a string containing all the classes of an element like this:
var classes = $('[class^="menu-icon-"]').attr('class');
The string prints something like this: "foo menu-icon-icon-name bar"
How can find out what the "icon-name" part in the string is, whatever it may be?
It will always be with a class formatted as "menu-icon-{icon-name-here}" among whatever other classes the element may contain.
This works in all cases-
var menuname = classes.substr(classes.indexOf("menu-icon") + 10).split(" ")[0];
lets say you have one div's classes as a string
var class = "foo menu-icon-icon-name bar"
if you are certain that there will always be a space after "" you should be able to do something like
var name = class.match(/menu-icon-(.*) /)[1];