'Get String value if present or null if not present using Java8 Stream

I have a json similar like as shown below. The requirement is to get the key value based on the id. ie. lets say If Id is A1 key value should return 2gAwIBAgIQKGZsKfAUzaJHVantyrwVdzANBgkqhkiG9w0BAQs. The key array will always conatins only one element.

{
  "keys": [
    {
      "id": "A1",
      "key": [
        "2gAwIBAgIQKGZsKfAUzaJHVantyrwVdzANBgkqhkiG9w0BAQs"
      ]
    },
     {
      "id": "A2",
      "key": [
        "swKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sfsf2dew"
      ]
    },
     {
      "id": "A3",
      "key": [
        "EyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3Mubdwe2"
      ]
    }
  ]
}

To implement the above I have wrote the below code using Java8 Stream but the problem is that it returns Optional<KeyDetails> which again I needs to parse and get the key value

String keyDetails = "{\"keys\":[{\"id\":\"A1\",\"key\":[\"2gAwIBAgIQKGZsKfAUzaJHVantyrwVdzANBgkqhkiG9w0BAQs\"]},{\"id\":\"A2\",\"key\":[\"swKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sfsf2dew\"]},{\"id\":\"A3\",\"key\":[\"EyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3Mubdwe2\"]}]}";
AccessKeys accessKeys = new ObjectMapper().readValue(keyDetails, AccessKeys.class);
Optional<KeyDetails> filteredKey = accessKeys.getKeys().stream().filter(key-> key.getId().equals("A3")).findAny();
if(filteredKey.isPresent()) {
    String keyValue = filteredKey.get().getKey().get(0);
    System.out.println("keyValue==>"+keyValue);
}

What I want is to get Optional<String> instead of Optional<KeyDetails>. i.e if the id is present it should return just the key value which is present within the key array.

Some condition that the json satisfies were:

  • Sometimes there can be a situation for duplicate key id, in that case it should pick only one (first one)
  • Key array will always contains one string value

Can anyone please help me on this



Solution 1:[1]

The key is to use tidyr::separate_rows(table, colname, separator).

A wrapper:

STRINGdb.reformat.ann.table.per.gene <- function(path_of_tsv = '/Users/.../enrichment.DISEASES.tsv'
                                                 , column = 'matching proteins in your network (labels)'
                                                 , sep = ',') {
  
  annotation_tsv <- CodeAndRoll2::read.simple.tsv(path_of_tsv)
  stopifnot(column %in% colnames(annotation_tsv))
  (tbl_split <- tidyr::separate_rows(data = annotation_tsv, column, sep = sep ))
  CodeAndRoll2::write.simple.tsv(tbl_split, ManualName = ppp((path_of_tsv), "per.gene.tsv"))
  return(tbl_split)
}

Solution 2:[2]

You may have a couple of ways to make it:

  • Base R option using stack
with(df,  rev(stack(setNames(strsplit(Location, ", "), Fruit))))
  • data.table option
setDT(df)[, .(Location = unlist(strsplit(Location, ", "))), Fruit]
  • tidyr option using unnest
df %>%
  mutate(Location = strsplit(Location, ", ")) %>%
  unnest(Location)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 bud.dugong
Solution 2 ThomasIsCoding