Create one object out of two separate arrays based on index - javascript

I'm trying to take this array of arrays,
const parsedCsvData = [
[
"Passage",
"Percentage of",
"constraint2",
"1",
"2",
"",
"",
"",
"",
"",
"",
""
],
[
"",
"",
"",
"",
"",
"",
"",
"",
"Avg A Param",
"",
"0.3",
"0.9"
],
[
"Item",
"Include",
"constraint1",
"1",
"4",
"",
"",
"",
"",
"",
"",
""
],
[
"",
"",
"",
"",
"",
"",
"",
"",
"Item Identifier",
"I105_15201",
"",
""
]
]
and populate this object with their values
const template = {
"attributeName": "",
"constraintType": "",
"objectType": "",
"filters": [
{
"objectType": "",
"attributeName": "",
"values": "",
"valueLowerBound": "",
"valueUpperBound": ""
}
],
"upperBound": "",
"description": "",
"lowerBound": ""
}
each array from parsedCsvData was a row in a CSV file I parsed. Each value in the array of arrays is indexed based off another array
const csvHeaders = [
"objectType",
"constraintType",
"description",
"lowerBound",
"upperBound",
"attributeName",
"referenceValue",
"scope",
"filters",
"values",
"valueLowerBound",
"valueUpperBound"
]
For example, in the first sub array of parsedCsvData Passage is at index 0 and the value for objectType in csvHeaders. Similarly, description is at index 2 and is constraint1 and constraint2 respectively.
Additionally, if there exists a filters value at index 8 in the csv a new row was created. After parsing, this created a new sub array for each filter value. However, each filters value and the following three, values, valueLowerBound and valueUpperBound belong in the same template object as a subarray under the filters key.
Here is an example of the output I am trying to accomplish given what I posted above. Never mind the empty key/value pairs.
[{
"constraintType": "Percentage of",
"objectType": "Passage",
"filters": [
{
"attributeName": "Avg A Param",
"values": "",
"valueLowerBound": "0.3",
"valueUpperBound": "0.9"
} // there may be multiple filter objects as part of this array
],
"upperBound": "2",
"description": "constraint2",
"lowerBound": "1"
},
{
"constraintType": "Include",
"objectType": "Item",
"filters": [
{
"attributeName": "Item Identifier",
"values": "I105_15201",
"valueLowerBound": "",
"valueUpperBound": ""
}
],
"upperBound": "4",
"description": "constraint1",
"lowerBound": "1"
}
]
I've tried mapping the csvHeaders array, attempting to use their indices and then do a map of the the parsedCsvData values and assign them to the template object, but can't seem to get it to work. Any help would be much appreciated.

An approach by checking the first element of the nested arra for either assign a new object or assign a new nested object.
const
parsedCsvData = [["Passage", "Percentage of", "constraint2", "1", "2", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", "Avg A Param", "", "0.3", "0.9"], ["Item", "Include", "constraint1", "1", "4", "", "", "", "", "", "", ""], ["", "", "", "", "", "", "", "", "Item Identifier", "I105_15201", "", ""]],
template = ["objectType", "constraintType", "description", "lowerBound", "upperBound", "xxxx", "referenceValue", "scope", "attributeName", "values", "valueLowerBound", "valueUpperBound"],
result = parsedCsvData.reduce((r, a) => {
const
assign = (object, target, value) => {
const
keys = target.split('.'),
last = keys.pop();
keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
};
if (a[0]) {
r.push(a.reduce((t, v, i) => {
if (v) assign(t, template[i], v);
return t;
}, {}));
} else {
r[r.length - 1].filters = r[r.length - 1].filters || [];
r[r.length - 1].filters.push(a.reduce((t, v, i) => {
if (v) assign(t, template[i], v);
return t;
}, {}));
}
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

How to extract a set of isolated 2D arrays from a larger 2D array?

Let's say I have a 2D array filled with a lot of blank spaces, but there are smaller isolated 2D arrays contained between these blanks. For example:
var aVO = [
["col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8", "col9"],
["", "", "", "", "", "", "", "", ""],
[1, 2, 3, "", "", "", "", "", ""],
[4, 5, 6, "", "", "a", "b", "", ""],
[7, 8, 9, "", "", "c", "d", "", 1],
["", "", "", "", "", "", "", "", 2],
["", "", "z", "y", "", "", "", "", 3],
["", "x", "w", "v", "", 7, 7, 7, ""],
["", "", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", "", ""],
["", "A1", "B1", "", "", "", "", "", ""],
["", "A2", "B2", "C2", "", "", "HELLO", "", ""]
]
I'm interested in converting this into eight 2D arrays:
[["col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8", "col9"]]
[[1,2,3],[4,5,6],[7,8,9]]
[["a","b"],["c","d"]]
[[1],[2],[3]]
[["", "z","y"],["x","w", "v"]]
[[7,7,7]]
[["A1","B1",""],["A2","B2","C2"]]
[["HELLO"]]
What's the best approach to extract these smaller 2D arrays? I was thinking about iterating row-by-row but it's hard to visualize how to elegantly extract data like [["", "z","y"],["x","w","v"]] (note how "x" isn't directly below "z", and therefore the resulting 2D array needs to reflect that shift). Thanks for any help!
Here's an approach using Set and Map instances to keep track of groups of cells:
Create cells out of the 2d array
Create an empty Map in which we will store for each cell with a value to which group it belongs
Loop over each cell
If a cell is empty, go to the next one
If a cell has a value
Create a group for it. The group marks a top left and bottom right position and keeps track of a set of cells that belong to it.
Check which adjacent cells already belong to a group
Merge the newly created group with all of the groups found for adjacent cells
Collect all unique groups from the Map
For each unique group, slice out the part between its top left and bottom right corner from the initial grid
const Cell = memo(
(r, c) => ({ r, c }),
([r, c]) => `${r}_${c}`
);
Cell.neighbors = ({ r, c }) => [
Cell(r, c + 1), // Right
Cell(r + 1, c), // Down
Cell(r, c - 1), // Left
Cell(r - 1, c), // Up
];
// Create a single-cell group
const Group = (cell) => ({
minR: cell.r,
maxR: cell.r + 1,
minC: cell.c,
maxC: cell.c + 1,
cells: new Set([cell])
});
// Merge two groups into a new one
Group.merge = (g1, g2) => ({
minR: Math.min(g1.minR, g2.minR),
maxR: Math.max(g1.maxR, g2.maxR),
minC: Math.min(g1.minC, g2.minC),
maxC: Math.max(g1.maxC, g2.maxC),
cells: new Set([ ...g1.cells, ...g2.cells ])
});
// Take a grid and slice out the part covered by a group
Group.extractFromGrid = grid => ({ minR, maxR, minC, maxC }) => grid
.slice(minR, maxR)
.map(row => row.slice(minC, maxC));
// Create all cells with their values
const grid = getData();
const allCells = grid.flatMap(
(row, ri) => row.map(
(value, ci) => Cell(ri, ci)
)
);
const groupPerCell = new Map();
allCells.forEach(current => {
const inIsland = grid[current.r][current.c] !== "";
if (inIsland) {
const newGroup = Cell
.neighbors(current)
.filter(c => groupPerCell.has(c))
.map(c => groupPerCell.get(c))
.reduce(Group.merge, Group(current));
// Store a reference to the group for each member
newGroup.cells.forEach(c => {
groupPerCell.set(c, newGroup);
});
}
});
const allGroups = [...new Set(groupPerCell.values())];
const allValues = allGroups.map(Group.extractFromGrid(grid));
console.log(allValues);
function memo(f, hash) {
const cache = {};
return (...args) => {
const k = hash(args);
if (!cache[k]) cache[k] = f(...args);
return cache[k];
}
}
function getData() { return [
["col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8", "col9"],
["", "", "", "", "", "", "", "", ""],
[1, 2, 3, "", "", "", "", "", ""],
[4, 5, 6, "", "", "a", "b", "", ""],
[7, 8, 9, "", "", "c", "d", "", 1],
["", "", "", "", "", "", "", "", 2],
["", "", "z", "y", "", "", "", "", 3],
["", "x", "w", "v", "", 7, 7, 7, ""],
["", "", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", "", ""],
["", "A1", "B1", "", "", "", "", "", ""],
["", "A2", "B2", "C2", "", "", "HELLO", "", ""]
]; }

Advice for deeply nested filtering with nested object for RXJS in angular?

Quick Question:
Pardon me, I'm fairly new to Typescipt & RxJS. I have the following JSON:
[
{
"ID": "",
"UEN": "",
"Name": "",
"Address": "",
"Telephone": "",
"Fax": "",
"Email": "",
"Website": "",
"Postal": "",
"Status": ,
"TimeCreated": ,
"TimeUpdated": ,
"Workheads": [{
"ID": "",
"Name": "",
"Code": ""
},
{
"ID": "",
"Name": "",
"Code": ""
}
]
},
...
]
This json is feed into my angular app via Observable from HTTP get().
How do I filter the workhead.Code section such that I could get those relevant Json objects within the array by matching the inner workhead.Code to a specific string that has been provided by the user (e.g. workhead.Code == 'CS2230')?
Help appreciated.
You are not clear exactly what you want returned. I assume you want the full objects returned, and not only the inner "Workheads". You can use a filter() to get what you want:
const data = [{
"ID": "",
"UEN": "",
"Name": "",
"Address": "",
"Telephone": "",
"Fax": "",
"Email": "",
"Website": "",
"Postal": "",
"Status": "",
"TimeCreated": "",
"TimeUpdated": "",
"Workheads": [{
"ID": "",
"Name": "",
"Code": "abc"
}, {
"ID": "",
"Name": "",
"Code": "def"
}]
}];
// Returns an array of the objects which contain matching code.
const getRelatedByCode = (arr, userProvidedCode) => {
return arr.filter((i) => {
return (i.Workheads || [])
.some(wh => wh.Code === userProvidedCode);
});
}
console.log(getRelatedByCode(data, 'abc')); // Returns array with the object
console.log(getRelatedByCode(data, 'zzz')); // Returns empty array

Json data reading using jquery [duplicate]

This question already has answers here:
How can I access object properties containing special characters?
(2 answers)
Closed 6 years ago.
how can i get the value of User[keywords][] using jquery ? i tried to get like console.log(User[keywords]); but it does not work
{
"User[firstName]": "",
"User[lastName]": "",
"User[city]": "",
"User[countryCode]": "",
"User[gender]": "",
"User[userType]": "",
"User[zip]": "",
"User[email]": "",
"User[age]": "",
"User[fullAddress]": "",
"CustomValue[11][fieldValue]": "",
"CustomValue[5][fieldValue]": "",
"CustomValue[1][fieldValue]": "",
"CustomValue[6][fieldValue]": "",
"CustomValue[7][fieldValue]": "",
"CustomValue[2][fieldValue]": "",
"CustomValue[8][fieldValue]": "",
"CustomValue[9][fieldValue]": "",
"CustomValue[4][fieldValue]": "",
"CustomValue[10][fieldValue]": "",
"CustomValue[3][fieldValue]": "",
"User[teams][]": null,
"": "",
"User[keywords][]": [
"52",
"53",
"54"
],
"User[searchType]": "1",
"User[keywordsExclude][]": null,
"User[id]": "",
"yt1": ""
}
If this json is assigned to variable obj:
console.log(obj['User[keywords][]']);
I suppose you need to use your data with [] square brackets to target specific keys:
var data = {
"User[firstName]": "",
"User[lastName]": "",
"User[city]": "",
"User[countryCode]": "",
"User[gender]": "",
"User[userType]": "",
"User[zip]": "",
"User[email]": "",
"User[age]": "",
"User[fullAddress]": "",
"CustomValue[11][fieldValue]": "",
"CustomValue[5][fieldValue]": "",
"CustomValue[1][fieldValue]": "",
"CustomValue[6][fieldValue]": "",
"CustomValue[7][fieldValue]": "",
"CustomValue[2][fieldValue]": "",
"CustomValue[8][fieldValue]": "",
"CustomValue[9][fieldValue]": "",
"CustomValue[4][fieldValue]": "",
"CustomValue[10][fieldValue]": "",
"CustomValue[3][fieldValue]": "",
"User[teams][]": null,
"": "",
"User[keywords][]": [
"52",
"53",
"54"
],
"User[searchType]": "1",
"User[keywordsExclude][]": null,
"User[id]": "",
"yt1": ""
};
var pre = '<pre>'+ JSON.stringify(data["User[keywords][]"], 0, 0) +'</pre>'
document.write(pre)

Not getting array from object

I am using map method to convert from an object to an array. What is the issue in the following code?
var data = {
"productName": "fsdfsdf",
"productDesc": "",
"category": null,
"categoryName": "",
"style": null,
"styleName": "",
"substyle": null,
"substyleName": "",
"store": null,
"storeName": "",
"stand": null,
"standName": "",
"rack": null,
"rackName": "",
"roll": null,
"rollName": "",
"color": null,
"width": "",
"widthunit": "meter",
"length": 0,
"lengthunit": "meter",
"pieces": "",
"cutofquantity": "",
"estimatedConsumption": ""
}
var key = $.map(data, function(value, index) {
return index;
});
var value = $.map(data, function(value, index) {
return value;
});
console.log(value)
Please refer to this JSFiddle for a live example.
Because you have length: 0 as one of your properties, jQuery thinks that the object is an array instead of an object.
It then loops over the numerical indexes from 0 to 0 (not inclusive) and generates a zero length array.
Here is the alternate if you want to use with length:0
var data = {
"productName": "fsdfsdf",
"productDesc": "",
"category": null,
"categoryName": "",
"style": null,
"styleName": "",
"substyle": null,
"substyleName": "",
"store": null,
"storeName": "",
"stand": null,
"standName": "",
"rack": null,
"rackName": "",
"roll": null,
"rollName": "",
"color": null,
"width": "",
"widthunit": "meter",
"length": 0,
"lengthunit": "meter",
"pieces": "",
"cutofquantity": "",
"estimatedConsumption": ""
};
for(var key in data) {
if(data.hasOwnProperty(key)) {
console.log(key) ;
console.log(data[key]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You could do something like this below:
var data = {
"productName": "fsdfsdf",
"productDesc": "",
"category": null,
"categoryName": "",
"style": null,
"styleName": "",
"substyle": null,
"substyleName": "",
"store": null,
"storeName": "",
"stand": null,
"standName": "",
"rack": null,
"rackName": "",
"roll": null,
"rollName": "",
"color": null,
"width": "",
"widthunit": "meter",
"length": 0,
"lengthunit": "meter",
"pieces": "",
"cutofquantity": "",
"estimatedConsumption": ""
};
var arr = Object.keys(data).map(function(k) { return data[k] });
console.log(arr)
Fiddle to play around: https://jsfiddle.net/u5t4L55g/
Loop through each property of the object and push the key and value in array like below. Hope this will help you.
var data = {
"productName": "fsdfsdf",
"productDesc": "",
"category": null,
"categoryName": "",
"style": null,
"styleName": "",
"substyle": null,
"substyleName": "",
"store": null,
"storeName": "",
"stand": null,
"standName": "",
"rack": null,
"rackName": "",
"roll": null,
"rollName": "",
"color": null,
"width": "",
"widthunit": "meter",
"length": 0,
"lengthunit": "meter",
"pieces": "",
"cutofquantity": "",
"estimatedConsumption": ""
}
var value = [];
var key = [];
for (var property in data) {
key.push(property);
value.push(data[property]);
}
console.log(value)
var key = Object.keys(data).map(function(index, value) { return index });
var value = Object.keys(data).map(function(index, value) { return data[index] });
So it is giving key and value pairs

Find and update nested JSON value

I need to find and update json object from nested json object. Consider the original json object.
var originaldata=[
{
"sc_iden": "331",
"sc_name": "Scene 1",
"sc_type": "",
"sc_status": "Draft",
"sc_owner": "",
"children": [
{
"sc_iden": "332",
"Sc_name": "Scene1.1",
"sc_type": "",
"sc_status": "Draft",
"sc_priority": "3",
"sc_owner": "",
"children": []
}
]
},
{
"sc_iden": "334",
"sc_name": "Scene2",
"sc_type": "",
"sc_status": "Draft",
"sc_priority": "2",
"sc_owner": "",
"children": []
}]
Find the below findUpdate record from originaldata(JSON) and update their values.
var findUpdate = {
"sc_iden": "332",
"Sc_name": "My Scene",
"sc_type": "New Type",
"sc_status": "Opened",
"sc_priority": "5",
"sc_owner": "Admin",
"children": []
}
Based on sc_iden ="332" search the originaldata and update new values(findUpdate) by using jquery or angularjs.
Have a look on this plunker .
var update = function(jsonArray, updatedJson) {
if (jsonArray.length !== 0) {
jsonArray.forEach(function(obj) {
if (obj.sc_iden === updatedJson.sc_iden) {
obj.sc_name = updatedJson.sc_name;
//....update
} else {
//try to update children
update(obj.children, updatedJson);
}
});
}
};
It will modify the original data, so keep a copy if you still need that.
Check the console output (in the example only Sc_name is changed):
var originaldata=[
{
"sc_iden": "331",
"sc_name": "Scene 1",
"sc_type": "",
"sc_status": "Draft",
"sc_owner": "",
"children": [
{
"sc_iden": "332",
"Sc_name": "Scene1.1",
"sc_type": "",
"sc_status": "Draft",
"sc_priority": "3",
"sc_owner": "",
"children": []
}
]
},
{
"sc_iden": "334",
"sc_name": "Scene2",
"sc_type": "",
"sc_status": "Draft",
"sc_priority": "2",
"sc_owner": "",
"children": []
}];
var findUpdate = {
"sc_iden": "332",
"Sc_name": "My Scene",
"sc_type": "New Type",
"sc_status": "Opened",
"sc_priority": "5",
"sc_owner": "Admin",
"children": []
}
for (i in originaldata) {
var obj = originaldata[i];
if (obj['sc_iden'] == '332') {
obj['Sc_name'] = findUpdate['Sc_name'];
//...
} else {
for (m in obj['children']) {
var k = obj['children'][m];
if (k['sc_iden'] == '332') {
k['Sc_name'] = findUpdate['Sc_name'];
//...
}
}
}
}
console.log(originaldata);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Categories

Resources