Reputation: 1655
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);
Upvotes: 0
Views: 217
Reputation: 5734
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)
Upvotes: 1
Reputation: 201
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
Upvotes: 1