0

I have an nested array with objects docs, which I first flatten to one level. And I have another flat array called multiValueSelected.

Now I'd like to iterate through all objects of the flattened docs-array and check if the key is also in the multiValueSelected-array.

If so, I would like to copy the entire docs-array for every comma separated value for the specific key, copy all other objects and add the new doc to the table.

With this following approach, I'm able to iterate through all comma separated values, but how can I duplicate the entire docs-array? Thank you for your help.

Example Arrays:

docs [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...]

multiValueSelected {"color, size, ..."}

Expected result for data:

1. {"id" : "test1", "color" : "green", "size" : ""}
2. {"id" : "test1", "color" : "blue", "size" : ""}
3. {"id" : "test1", "color" : "grey", "size" : ""}
4. {"id" : "test1", "color" : "", "size" : "s"}
5. {"id" : "test1", "color" : "", "size" : "m"}

6. {"id" : "test2", "color" : "green", "size" : "l"}

Script:

function importTableau(docs, table) {

  var data = [];
  var importedDocs = 0;

  for (var i = 0; i < docs.length; i++) {

    var flatten = objectFlattenData(docs[i])
    var rec = {}

    for (var key in flatten) {
       // var key deiines the KEY
       // var flatten[key] defines the VALUE without duplicates
       // var flatten defines the CURRENT DOCUMENT

       if (multiValueSelected.indexOf(key) > -1) {
         //console.log('key: ', key, ' flatten: ', flatten[key])
         var flattenString = flatten[key];

         var id = key.replace(/[^A-Za-z0-9_]+/g, '')

         // handling multivalues as seperate doc per value
         var properties = flattenString.split(',');
         var propertiesLength = properties.length;

         for (var i = 0; i < propertiesLength; i++) {
            // Trim the excess whitespace.
            properties[i] = properties[i].replace(/^\s*/, "").replace(/\s*$/, "");
            // Get the single Value
            var singleValue = properties[i]
            console.log(singleValue);

            rec[id] = flatten[singleValue];

            data.push(rec);

         }
         return false;
         
       } else {

         // not selected for handling multivalues as seperate doc
         var id = key.replace(/[^A-Za-z0-9_]+/g, '')
         rec[id] = flatten[key];

       };

    };

    data.push(rec);

  };

  table.appendRows(data);
2
  • 3
    Some simplified example data and expected results would be really useful to understand the question Commented Dec 29, 2020 at 16:29
  • Thx for your comment. I've edited the question Commented Dec 29, 2020 at 16:43

2 Answers 2

1

It seems a little confusing your expected output, but maybe this is what you want?

let docs = [{
  "id": "test1",
  "color": "green,blue,grey",
  "size": "s,m"
}, {
  "id": "test2",
  "color": "green",
  "size": "l"
}];

let multiValueSelected = ["color", "size"];

let data = [];

for (selected_value of multiValueSelected) {
  for (doc of docs) {
    if (doc.hasOwnProperty(selected_value)) {
      let values = doc[selected_value].split(',');
      for (value of values) {
        let obj = {id: doc.id};
        let keys = Object.keys(doc).filter(k => !['id', selected_value].includes(k));
        keys.map(k => obj[k] = '');
        obj[selected_value] = value;
        data.push(obj);
      }
    }
  }
}

console.log(data)

Sign up to request clarification or add additional context in comments.

1 Comment

Great approach and almost right. For the object with the id 'test2', only one array may be created, since the objects of the array do not contain any multiple values. Sorry for the confusion!
1

I really have not understand the question, but if you want to have this:

Input: docs [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...]

Output: multiValueSelected ["color, size, ...", "...."]

as an output you can't have [{"color, size, ..."}] because is not a valid json, a json is a composition of key-value pair and not just only a string

You can do this:

const docs = [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...];

const multiValueSelected = [];

docs.forEach(doc => {
   let currentValue = "";
   Object.keys(doc).forEach(key => {
      if(doc[key].split(',').length > 1)
        currentValue = (currentValue === "") ? key : ", " + key;
   }
   if(currentValue !== "") multiValueSelected.push(currentValue);
}

if you want as output this [{"color": "green,blue,grey" , "size" : "s,m" }, {"....": "....", ....}]

const docs = [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...];
    
const multiValueSelected = [];

docs.forEach(doc => {
   const currentValue = {};
   Object.keys(doc).forEach(key => {
      if(doc[key].split(',').length > 1)
        currentValue[key] = doc[key];
   }
   if(Object.keys(currentValue).length > 0) multiValueSelected.push(currentValue);
}

please let me know if I have not responded to your question

2 Comments

Thx four your reply! multiValueSelected is a simple array, sorry. This array contains possible object-keys of the docs-array. If the docs-array contains an object which contains a key defined in multiValueSelected, then I would like to check the value of it and how many comma seperated values are in the object. For each comma seperated value I'd like to add a new doc and leave all other keys of the multiValueSelected array empty. Then I iterate the same through the next multiValueSelected key and doing the same. All other objects in the doc should be copied.
I've edited my question and changed the multiValueSelected-Example from JSON to array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.