Merging two arrays without any duplicates [VB.NET] - vb.net

The question being asked is as follows:
Implement the UniqueNames method. When passed two arrays of names, it will return an array containing the names that appear in either or both arrays. The returned array should have no duplicates.
For example, calling MergeNames.UniqueNames({'Ava', 'Emma', 'Olivia'}, {'Olivia', 'Sophia', 'Emma'}) should return an array containing Ava, Emma, Olivia, and Sophia in any order.
Starting Code:
Module Module1
Public Class MergeNames
Public Shared Function UniqueNames(names1() As String, names2() As String) As String()
Throw New NotImplementedException()
End Function
End Class
Public Sub Main()
Dim names1() As String = {"Ava", "Emma", "Olivia"}
Dim names2() As String = {"Olivia", "Sophia", "Emma"}
Console.WriteLine(string.Join(", ", MergeNames.UniqueNames(names1, names2))) ' should print Ava, Emma, Olivia, Sophia
End Sub
End Module

LINQ would be the easiest way to go here:
Dim combinedUniqueNames = names1.Union(names2).Distinct().ToArray()
Union will combine two lists, Distinct will remove duplicates and ToArray creates a new array from the result. As is pretty much always the case with LINQ extension methods, they can all be called on any IEnumerable(Of T). Your String arrays implement IEnumerable(Of String).
EDIT:
As per Jimi's comment, we just need:
Dim combinedUniqueNames = names1.Union(names2).ToArray()
I guess I should have realised, given that 'union' is a set operation and does exclude duplicates in a mathematical context.

import java.util.ArrayList;
import java.util.List;
public class MergeNames {
public static String[] uniqueNames(String[] names1, String[] names2) {
List<String> list= new ArrayList<String>();
for (String name: names1) {
if(!list.contains(name)) {
list.add(name);
}
}
for (String name: names2) {
if(!list.contains(name)) {
list.add(name);
}
}
String[] a= list.toArray(new String[list.size()]);
return a;
}
public static void main(String[] args) {
String[] names1 = new String[] {"Ava", "Emma", "Emma","Olivia"};
String[] names2 = new String[] {"Olivia", "Sophia", "Emma"};
System.out.println(String.join(", ", MergeNames.uniqueNames(names1, names2))); // should print Ava, Emma, Olivia, Sophia
}
}

Related

Formatting YAML with Jackson

I am using the Jackson library to convert Java objects to YAML format. Based on the documentation I found on the Internet, I was able to quickly write a function that does the conversion.
I am seeking to convert the following classes to YAML:
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
public class ParamInfo
{
private String paramName;
private String paramType;
// getters and setters
}
Using Jackson's ObjectMapper, I can easily generate the YAML:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory());
RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}
The YAML I get is below:
---
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
The YAML I get is OK, but it has some problems in my eyes. One probem is the "---" that it begins with. Another is the fact that I would like to be able to group the information in a manner similar to the YAML below:
RequestInfo:
thePath: "/"
theMethod: "GET"
theURL: "http://localhost:8080/"
theParams:
- paramName: "resource"
paramType: "path"
All of the examples I am seeing on the Internet use an Employee class, and talk about how to convert that class to YAML, but do not tell how to avoid the "---" (or change it into soething more descriptive). I also cannot find anything that tells how to group the YAML in the manner I describe.
Does anyone know how to do this? Is there a way to eliminate the "---", or create a name (like "RequestInfo") that groups together the translated data in an object?
You can ignore --- by disable YAMLGenerator.Feature.WRITE_DOC_START_MARKER..
If you want to wrap value under class name then u need to use #JsonRootName...
Try with this:
RequestInof class:
#JsonRootName("RequestInfo")
public class RequestInfo
{
private String thePath;
private String theMethod;
private String theURL;
private List<ParamInfo> theParams = new ArrayList<>();
// getters and setters
}
Test:
public String basicTest()
{
ObjectMapper theMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
theMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); RequestInfo info = new RequestInfo();
info.setThePath("/");
info.setTheMethod("GET");
info.setTheURL("http://localhost:8080/");
List<ParamInfo> params = new ArrayList<>();
params.add(new ParamInfo("resource","path"));
info.setTheParams(params);
String ret = null;
try
{
ret = theMapper.writeValueAsString(info);
}
catch(Exception exe)
{
logger.error(exe.getMessage());
}
return(ret);
}

How to pass bean class to a test method in testng?

I have an Excel Util which reads all the data from excel sheet. The excel sheet has 10 columns like time, sourceType, tid, message, severity,
lastModify, entityName, operationType, replayId, recordIds.
My DataProvider has code something like this which returns all the 10 columns and their values.
#DataProvider(name="googleData")
public static Object[][] testData() {
String filePath = "/Users/TestUser/Workspace/FixProject/ExcelCheck/src/test/resources/excelreader.xlsx";
Object[][] arrayObject = excelFileUtils.getExcelData(filePath, "excelreader");
return arrayObject;
}
In My TestMethod, I have to pass all these 10 columns or else it wont allow me to run. Instead I want to create a Bean Class and pass something like this to my test method
#Test(dataProvider = "googleData", dataProviderClass = DataProviders.class)
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
How do we achieve this?
Using the dataProvider you have, your test method is going to run 10 times for each object in the array.
What you can do is to create an object, convert your dataProvider into that object and than use it your test method code.
Object myDataHelper = null;
#Test()
public void testGoogleData(BeanClass object) {
myDataHelper = convertDataProviderToObject();
// use it here in a for/for each loop
System.out.println(object.getTid());
}
public static Object[][] read_excel(String Sheet_Name) throws Exception
{
File obj = new File("./src/main/java/com/Demo/TestData/Test_Data.xlsx");
FileInputStream fis = new FileInputStream(obj);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheet(Sheet_Name);
int row_number = sheet.getLastRowNum();
int column_number = sheet.getRow(0).getLastCellNum();
Object data[][] = new Object[row_number][column_number];
wb.close();
for(int i=0; i<row_number; i++)
{
for(int j=0; j<column_number; j++)
{
data[i][j] = sheet.getRow(i + 1).getCell(j).toString();
}
}
return data;
}
#DataProvider
public Object[][] getDataFromExcel() throws Exception
{ Object[][] data = Utility.read_excel("Admin_Credentials");//Sheet name
return data;
}
#Test(dataProvider="getDataFromExcel")
It is supported in QAF-TestNG extension. You can have one or more complex object argument in your test method while using inbuilt or custom data provider. For excel your code may look like below:
#QAFDataProvider(dataFile = "resources/data/googletestdata.xls")
#Test
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
For custom data provider it may look like below:
#QAFDataProvider
#Test(dataProvider = "googleData", dataProviderClass = DataProviders.class)
public void testGoogleData(BeanClass object) {
System.out.println(object.getTid());
}
You need to make sure that,properties name in your bean class must match column names (in any order). When using custom data provider you need to return Iterator for List of Map<String, Object> or Object[][] having Map, refer few example if you required to create custom data provider.

Jackson one item parse

I'm trying to parse openweathermap.org api
WeatheModel.java
public class WeatherModel {
private ListDays[] listDays;
#JsonProperty("list")
public ListDays[] getListDays() {
return listDays;
}
and two classes here http://pastebin.com/vySPfRSS
Main.java
public class Main {
public static final String WEATHER = "JSON from http://api.openweathermap.org/data/2.5/forecast/daily?q=London&mode=json&units=metric&cnt=7"
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
WeatherModel rootNode = mapper.readValue(WEATHER, WeatherModel.class);
How to get one (now it a list of 7 items ) item from WeatherModel?
Simply use the index to access object from an array.
ListDays[] listDays = rootNode.getListDays();
ListDays first = listDays[0];
ListDays second = listDays[1];
Arrays are sequences of objects and in the case above you describe an array of 7 ListDays. The first object uses index 0, the second object uses index 1 and so on. The [0] simply means that you retrieve the first object from the array. The length of the array can be determined by invoking listDays.length.
To loop through all of the elements you can use a for-loop.
for (ListDays l : listDays) {
// Here you have access to one ListDays-object. It is called l.
l.doStuff...
}

Sorting an ArrayList by two different properties

So I have a HashMap<String, Integer> which represents the number of times a certain word has been encountered in a sentence. What I want to do is put all the words in an ArrayList<String>, sorted first by the number of times a word has been encountered, and then break ties by alphabetical order. How would I go about doing that? My code looks something like this:
public class MyClass {
private HashMap<String, Integer> map;
public ArrayList<String> Order() {
ArrayList<String> temp = new ArrayList<>();
(...)
}
You'll need to use a custom comparator. For the comparison method, you'll need to return a negative value if the first argument should be treated as less than the second, 0 if they are equal, and a positive value if the first argument should be treated as greater than the second.
Note that this sorts the ArrayList in descending order according to the integer value
import java.util.Comparator;
import java.util.HashMap;
public class CustomComparator implements Comparator<String>
{
HashMap<String, Integer> map;
public CustomComparator(HashMap<String, Integer> comparisonMap)
{
map = comparisonMap;
}
#Override
public int compare(String s1, String s2)
{
int count1 = map.get(s1);
int count2 = map.get(s2);
if (count1 == count2)
return s1.compareTo(s2);
return count2 - count1;
}
}
Two steps to create and sort the ArrayList:
First, add every key from the HashMap to the ArrayList
ArrayList<String> result = new ArrayList<String>(map.size());
result.addAll(map.keySet());
Then, sort the ArrayList using the custom comparator:
Collections.sort(result, new CustomComparator(map));

How to iterate through a PORTION of a TreeMap?

I'm doing an assignment where I have to search through keys in a TreeMap (that are mapped to files that they are found in. Basically, this TreeMap is an Inverted Index) that start with a query word that we specify to the program in a query file. However, for efficiency purposes, my professor does not want is to iterate through ALL the keys in the TreeMap when we look for keys that start with the query words, rather she wants us to iterate through only the keys that we need to iterate through. For example, if the query word starts with C, then we should only iterate through the keys that start with C. Any ideas on how to approach this?
Use the TreeMap's subMap() method to obtain a SortedMap that contains only the range of keys that you want to examine. Then iterate over that SortedMap.
Here is the basic implementation of what #ottomeister suggested:
public class Tester{
public static void main(String a[]){
TreeMap<CustomObject,String> tm = new TreeMap<CustomObject,String>();
tm.put(new CustomObject(4,"abc"),"abc");
tm.put(new CustomObject(7,"bcd"),"bcd");
tm.put(new CustomObject(25,"cde"),"cde");
tm.put(new CustomObject(18,"def"),"def");
tm.put(new CustomObject(2,"efg"),"efg");
tm.put(new CustomObject(8,"fgh"),"fgh");
tm.put(new CustomObject(3,"aab"),"aab");
tm.put(new CustomObject(13,"aab"),"abb");
Map<CustomObject, String> sub = tm.subMap(new CustomObject(9,""),new CustomObject(20,""));
for(Map.Entry<CustomObject,String> entry : sub.entrySet()) {
CustomObject key = entry.getKey();
String value = entry.getValue();
System.out.println(key.getId() + " => " + value);
}
}
}
class CustomObject implements Comparable<CustomObject>{
private int id;
private String Name;
CustomObject(int id, String Name){
this.id = id;
this.Name = Name;
}
#Override
public int compareTo(#NotNull CustomObject o) {
return this.id - o.id;
}
public int getId(){
return this.id;
}
}
output:
13 => abb
18 => def