Nitneuq
Nitneuq

Reputation: 5012

How to format to json with difference between comma of data/key and comma from text?

I am trying to improve this code so that it can handle a specific case.

Currently it works, unless the user adds a text with a comma

Here is my input who work (look only "note" key/value)

Input_OK =  2020-11-25,note:my text,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14

In this case : my text is ok because there is no comma

Input_NOK =  2020-11-25,note:my text, doesn't work,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14

In this case : my text, doesn't work is not ok because there is comma

With this specific input 2020-11-25,note:my text, work now,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14 I try to have this output

[{"release_date":"2020-11-25","today":"2020-11-25","note0":"my text, work now"},{"release_date":"2020-09-14","start":"2020-09-14"}]

Here is my current code

// before this input I add string to a list<String> for each date like that [2020-11-25,note0:test, 2020-11-24,my text, with comma, 2020-11-15,today:2020-11-15, 2020-09-14,start:2020-09-14] 

//After I remove space and [ ]

// myinput 2020-11-25,today:2020-11-25,2020-11-25,note0:my text, with comma,2020-09-14,start:2020-09-14

      var inputItarable = myinput.toString().split(',').where((s) => s.isNotEmpty);
      print("inputItarable   ${inputItarable} ");
//inputItarable   [2020-11-25, today:2020-11-25, 2020-11-25, note0:my text, with comma, 2020-09-14, start:2020-09-14] 

      
      var i = inputItarable.iterator;
      
      var tmp = {};

      while (i.moveNext()) {
        var key = i.current; i.moveNext();

        var value = i.current.split(':');
        (tmp[key] ??= []).add(value);

      }


      var output1 = tmp.keys.map((key) {
        var map = {}; map['release_date'] = key;
        tmp[key].forEach((e) => map[e[0]] = e[1]);
        return map;
      }).toList();

      var output2=json.encode(output1);
      print("output2   $output2 ");
  // output2   [{"release_date":"2020-11-25","today":"2020-11-25","note0":"my text, with comma"},{"release_date":"2020-09-14","start":"2020-09-14"}]

[Edit] I have a spécific case, where user back ligne, and have an input like that

myinput 2020-11-25,today:2020-11-25,2020-11-25,note0:my text, 
with comma,2020-09-14,start:2020-09-14

in this example I don't know how to replace the back ligne between my text, and with comma by my text,\nwith comma

Upvotes: 1

Views: 151

Answers (1)

bluenile
bluenile

Reputation: 6029

Please check the code below or you may directly run it on Dartpad at https://dartpad.dev/1404509cc0b427b1f31705448b5edba3

I have written a sanitize function. What the sanitize function does is it sanitizes the text between the possibleStart and possibleEnd. Meaning it replaces all the commas in user input text with §. To do this it assumes that the user input starts with ,note: or ,note0: and ends with ,2020- or ,2021-. This sanitized string is passed to your code and in the end § is replaced with ",". Let me know if you have any questions.

import 'dart:convert';

String sanitize(
    String input, List<String> possibleStart, List<String> possibleEnd) {
  final String start = possibleStart.join("|");
  final String end = possibleEnd.join("|");

  final RegExp exp = RegExp("(?<=$start)(.*?)(?=$end)");
  final Iterable<Match> matches = exp.allMatches(input);
  matches.forEach((match) {
    input =
        input.replaceFirst(match.group(0), match.group(0).replaceAll(",", "§"));
    return true;
  });
  return input;
}

void main() {
  String myinput =
      "2020-11-25,today:2020-11-25,2020-11-25,note0:my text, with comma,2020-09-14,start:2020-09-14";

  myinput = sanitize(myinput, [",note:", "note\\d:"], [",20\\d\\d-"]);

  var inputItarable = myinput.toString().split(',').where((s) => s.isNotEmpty);
  print("inputItarable   ${inputItarable} ");
//inputItarable   [2020-11-25, today:2020-11-25, 2020-11-25, note0:my text, with comma, 2020-09-14, start:2020-09-14]

  var i = inputItarable.iterator;

  var tmp = {};

  while (i.moveNext()) {
    var key = i.current;
    i.moveNext();

    var value = i.current.split(':');
    (tmp[key] ??= []).add(value);
  }

  var output1 = tmp.keys.map((key) {
    var map = {};
    map['release_date'] = key;
    tmp[key].forEach((e) => map[e[0]] = e[1]);
    return map;
  }).toList();

  var output2 = json.encode(output1).replaceAll("§", ",");
  print("output2   $output2 ");
}

Upvotes: 1

Related Questions