I have 2 string like this
var a= '12,13,14,15,16';
var b='p,q,q,p,q';
I just need like this 12,15 represents p
and 13,14,16 represents q
How can I do this in Jquery/javascript.
var a = '12,13,14,15,16';
var b = 'p,q,q,p,q';
var as = a.split(",");
var bs = b.split(",");
if(as.length == bs.length)
{
var map = {};
for(var i = 0; i < as.length; ++i)
{
var asv = as[i];
var bsv = bs[i];
map[asv] = bsv;
}
console.log(map['13']); //q
}
or:
var a = '12,13,14,15,16';
var b = 'p,q,q,p,q';
var as = a.split(",");
var bs = b.split(",");
if(as.length == bs.length)
{
var map = {};
as.map(function(asv,idx){
return {asv:asv, bsv:bs[idx]};
})
.forEach(function(x){
map[x.asv] = x.bsv;
});
console.log(map['13']); //q
}
In answer to your comment, perhaps something like this would be better:
var a = '12,13,14,15,16';
var b = 'p,q,q,p,q';
var as = a.split(",");
var bs = b.split(",");
if(as.length == bs.length)
{
var map = {};
as.map(function(asv,idx){
return {asv:asv,bsv:bs[idx]};
})
.forEach(function(x){
if(!map[x.bsv])
{
map[x.bsv]=[];
}
map[x.bsv].push(x.asv);
});
console.log(map['q']); //["13", "14", "16"]
console.log(map['q'].join(",")); //"13,14,16"
}
Simple as this:
var a= '12,13,14,15,16';
var b='p,q,q,p,q';
var pValues=[], qValues=[]; //where to store the results
b.split(',').forEach(function(value, index){ //split the values from the b var
var aa=a.split(','); //split the values from the a var
if(value=='p') pValues.push(aa[index]);
if(value=='q') qValues.push(aa[index]);
});
console.log("pValues: "+pValues);
console.log("qValues: "+qValues);
var a= '12,13,14,15,16';
var b='p,q,q,p,q';
function getRepresentative(srcA, srcB, valA)
{
var mapIndexA = srcA && srcA.split(',').indexOf(valA);
var mapB = srcB.split(',');
return mapB && mapB[mapIndexA] || -1;
}
console.log(getRepresentative(a,b, '15'));
The function returns -1 if no corresponding map between A and B is found..
The following function takes the two strings and splits them with the comma, then iterates over the symbol-token pairings one by one. Whenever a new symbol is discovered, it gets added to symbols and an empty array is added to symbolToNumbers so that numbers for this symbol can be pushed onto the array.
At the end, we can iterate over symbols to display the list of numbers for each symbol. This code will work for any variety of symbols, not just 'p' and 'q'.
function findElements(numbers, symbols) {
var numberTokens = numbers.split(','),
symbolTokens = symbols.split(','),
symbolToNumbers = {},
symbols = [],
n = numberTokens.length;
if (n != symbolTokens.length) {
console.log('error: the lists must have the same length');
return;
}
for (var i = 0; i < n; ++i) {
var number = numberTokens[i],
symbol = symbolTokens[i];
if (symbolToNumbers[symbol] === undefined) {
symbols.push(symbol);
symbolToNumbers[symbol] = [];
}
symbolToNumbers[symbol].push(number);
}
for (var i = 0; i < symbols.length; ++i) {
var symbol = symbols[i],
numbers = symbolToNumbers[symbol];
console.log(symbol+': '+numbers.join(', '));
}
}
var a = '12,13,14,15,16';
var b = 'p,q,q,p,q';
findElements(a, b);
See this code running on JSFiddle: http://jsfiddle.net/0e1g2ryf/1/
Related
I'm using this script to export Google Sheets as a JSON file and it works perfectly fine. However in my sheet im using names like this "qwe_qwe" and when I'm exporting its being formatted to "qweqwe". Is it possible somehow to export file in raw format.
I believe that "var FORMAT_PRETTY = 'Pretty';" makes the difference, however I can't make it work without this variable.
UPD: Found that this function if (!isAlnum_(letter)) checking for Alphanumeric chars, so I've decided to add smthng like this if (!isAlnum_(letter) && !isAlnum_("_")), however it doesn't work.
// Includes functions for exporting active sheet or all sheets as JSON object (also Python object syntax compatible).
// Tweak the makePrettyJSON_ function to customize what kind of JSON to export.
var FORMAT_ONELINE = 'One-line';
var FORMAT_MULTILINE = 'Multi-line';
var FORMAT_PRETTY = 'Pretty';
var LANGUAGE_JS = 'JavaScript';
var LANGUAGE_PYTHON = 'Python';
var STRUCTURE_LIST = 'List';
var STRUCTURE_HASH = 'Hash (keyed by "id" column)';
/* Defaults for this particular spreadsheet, change as desired */
var DEFAULT_FORMAT = FORMAT_PRETTY;
var DEFAULT_LANGUAGE = LANGUAGE_JS;
var DEFAULT_STRUCTURE = STRUCTURE_LIST;
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{name: "Export JSON for this sheet", functionName: "exportSheet"},
{name: "Export JSON for all sheets", functionName: "exportAllSheets"}
];
ss.addMenu("Export JSON", menuEntries);
}
function makeLabel(app, text, id) {
var lb = app.createLabel(text);
if (id) lb.setId(id);
return lb;
}
function makeListBox(app, name, items) {
var listBox = app.createListBox().setId(name).setName(name);
listBox.setVisibleItemCount(1);
var cache = CacheService.getPublicCache();
var selectedValue = cache.get(name);
Logger.log(selectedValue);
for (var i = 0; i < items.length; i++) {
listBox.addItem(items[i]);
if (items[1] == selectedValue) {
listBox.setSelectedIndex(i);
}
}
return listBox;
}
function makeButton(app, parent, name, callback) {
var button = app.createButton(name);
app.add(button);
var handler = app.createServerClickHandler(callback).addCallbackElement(parent);;
button.addClickHandler(handler);
return button;
}
function makeTextBox(app, name) {
var textArea = app.createTextArea().setWidth('100%').setHeight('200px').setId(name).setName(name);
return textArea;
}
function exportAllSheets(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetsData = {};
for (var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
var rowsData = getRowsData_(sheet, getExportOptions(e));
var sheetName = sheet.getName();
sheetsData[sheetName] = rowsData;
}
var json = makeJSON_(sheetsData, getExportOptions(e));
displayText_(json);
}
function exportSheet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rowsData = getRowsData_(sheet, getExportOptions(e));
var json = makeJSON_(rowsData, getExportOptions(e));
displayText_(json);
}
function getExportOptions(e) {
var options = {};
options.language = e && e.parameter.language || DEFAULT_LANGUAGE;
options.format = e && e.parameter.format || DEFAULT_FORMAT;
options.structure = e && e.parameter.structure || DEFAULT_STRUCTURE;
var cache = CacheService.getPublicCache();
cache.put('language', options.language);
cache.put('format', options.format);
cache.put('structure', options.structure);
Logger.log(options);
return options;
}
function makeJSON_(object, options) {
if (options.format == FORMAT_PRETTY) {
var jsonString = JSON.stringify(object, null, 4);
} else if (options.format == FORMAT_MULTILINE) {
var jsonString = Utilities.jsonStringify(object);
jsonString = jsonString.replace(/},/gi, '},\n');
jsonString = prettyJSON.replace(/":\[{"/gi, '":\n[{"');
jsonString = prettyJSON.replace(/}\],/gi, '}],\n');
} else {
var jsonString = Utilities.jsonStringify(object);
}
if (options.language == LANGUAGE_PYTHON) {
// add unicode markers
jsonString = jsonString.replace(/"([a-zA-Z]*)":\s+"/gi, '"$1": u"');
}
return jsonString;
}
function displayText_(text) {
var output = HtmlService.createHtmlOutput("<textarea style='width:100%;' rows='20'>" + text + "</textarea>");
output.setWidth(400)
output.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(output, 'Exported JSON');
}
// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - columnHeadersRowIndex: specifies the row number where the column names are stored.
// This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData_(sheet, options) {
var headersRange = sheet.getRange(1, 1, sheet.getFrozenRows(), sheet.getMaxColumns());
var headers = headersRange.getValues()[0];
var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getMaxRows(), sheet.getMaxColumns());
var objects = getObjects_(dataRange.getValues(), normalizeHeaders_(headers));
if (options.structure == STRUCTURE_HASH) {
var objectsById = {};
objects.forEach(function(object) {
objectsById[object.id] = object;
});
return objectsById;
} else {
return objects;
}
}
// getColumnsData iterates column by column in the input range and returns an array of objects.
// Each object contains all the data for a given column, indexed by its normalized row name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - rowHeadersColumnIndex: specifies the column number where the row names are stored.
// This argument is optional and it defaults to the column immediately left of the range;
// Returns an Array of objects.
function getColumnsData_(sheet, range, rowHeadersColumnIndex) {
rowHeadersColumnIndex = rowHeadersColumnIndex || range.getColumnIndex() - 1;
var headersTmp = sheet.getRange(range.getRow(), rowHeadersColumnIndex, range.getNumRows(), 1).getValues();
var headers = normalizeHeaders_(arrayTranspose_(headersTmp)[0]);
return getObjects(arrayTranspose_(range.getValues()), headers);
}
// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
// - data: JavaScript 2d array
// - keys: Array of Strings that define the property names for the objects to create
function getObjects_(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty_(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
// Returns an Array of normalized Strings.
// Arguments:
// - headers: Array of Strings to normalize
function normalizeHeaders_(headers) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
var key = normalizeHeader_(headers[i]);
if (key.length > 0) {
keys.push(key);
}
}
return keys;
}
// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
// - header: string to normalize
// Examples:
// "First Name" -> "firstName"
// "Market Cap (millions) -> "marketCapMillions
// "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader_(header) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum_(letter)) {
continue;
}
if (key.length == 0 && isDigit_(letter)) {
continue; // first character must be a letter
}
if (upperCase) {
upperCase = false;
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty_(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise.
function isAlnum_(char) {
return char >= 'A' && char <= 'Z' ||
char >= 'a' && char <= 'z' ||
isDigit_(char);
}
// Returns true if the character char is a digit, false otherwise.
function isDigit_(char) {
return char >= '0' && char <= '9';
}
// Given a JavaScript 2d Array, this function returns the transposed table.
// Arguments:
// - data: JavaScript 2d Array
// Returns a JavaScript 2d Array
// Example: arrayTranspose([[1,2,3],[4,5,6]]) returns [[1,4],[2,5],[3,6]].
function arrayTranspose_(data) {
if (data.length == 0 || data[0].length == 0) {
return null;
}
var ret = [];
for (var i = 0; i < data[0].length; ++i) {
ret.push([]);
}
for (var i = 0; i < data.length; ++i) {
for (var j = 0; j < data[i].length; ++j) {
ret[j][i] = data[i][j];
}
}
return ret;
}
Sample Sheet:
Export to JSON (based on original code):
column headers were formatted using normalizeHeader_()
Output:
5:19:32 AM Notice Execution started
5:19:34 AM Info [
{
"columna": "A2",
"columnb": "B2",
"columnc": "C2"
},
{
"columna": "A_3",
"columnb": "B_3",
"columnc": "C_3"
}
]
5:19:34 AM Notice Execution completed
Export to JSON (raw format column header):
Change var objects = getObjects_(dataRange.getValues(), normalizeHeaders_(headers)); in getRowsData_() to var objects = getObjects_(dataRange.getValues(), headers);
Output:
5:20:04 AM Notice Execution started
5:20:06 AM Info [
{
"Column_A": "A2",
"Column_B": "B2",
"Column_C": "C2"
},
{
"Column_A": "A_3",
"Column_B": "B_3",
"Column_C": "C_3"
}
]
5:20:06 AM Notice Execution completed
Export to JSON (format column header but include '_')
Use (!isAlnum_(letter) && (letter != '_')) in normalizeHeader_()
Output:
5:28:11 AM Notice Execution started
5:28:13 AM Info [
{
"column_a": "A2",
"column_b": "B2",
"column_c": "C2"
},
{
"column_a": "A_3",
"column_b": "B_3",
"column_c": "C_3"
}
]
5:28:13 AM Notice Execution completed
There is one more solution, you can just remove !isAlnum_(letter) checking or add underscore to it.
You can use this script to export google sheets data to json format
// IMPORT
/**
* Imports JSON data to your spreadsheet Ex: IMPORTJSON("http://myapisite.com","city/population")
* #param url URL of your JSON data as string
* #param xpath simplified xpath as string
* #customfunction
*/
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
// EXPORT
// Includes functions for exporting active sheet or all sheets as JSON object (also Python object syntax compatible).
// Tweak the makePrettyJSON_ function to customize what kind of JSON to export.
var FORMAT_ONELINE = "One-line";
var FORMAT_MULTILINE = "Multi-line";
var FORMAT_PRETTY = "Pretty";
var LANGUAGE_JS = "JavaScript";
var LANGUAGE_PYTHON = "Python";
var STRUCTURE_LIST = "List";
var STRUCTURE_HASH = 'Hash (keyed by "id" column)';
/* Defaults for this particular spreadsheet, change as desired */
var DEFAULT_FORMAT = FORMAT_PRETTY;
var DEFAULT_LANGUAGE = LANGUAGE_JS;
var DEFAULT_STRUCTURE = STRUCTURE_LIST;
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [
{ name: "Export JSON for this sheet", functionName: "exportSheet" },
{ name: "Export JSON for all sheets", functionName: "exportAllSheets" }
];
ss.addMenu("Export JSON", menuEntries);
}
function makeLabel(app, text, id) {
var lb = app.createLabel(text);
if (id) lb.setId(id);
return lb;
}
function makeListBox(app, name, items) {
var listBox = app
.createListBox()
.setId(name)
.setName(name);
listBox.setVisibleItemCount(1);
var cache = CacheService.getPublicCache();
var selectedValue = cache.get(name);
Logger.log(selectedValue);
for (var i = 0; i < items.length; i++) {
listBox.addItem(items[i]);
if (items[1] == selectedValue) {
listBox.setSelectedIndex(i);
}
}
return listBox;
}
function makeButton(app, parent, name, callback) {
var button = app.createButton(name);
app.add(button);
var handler = app
.createServerClickHandler(callback)
.addCallbackElement(parent);
button.addClickHandler(handler);
return button;
}
function makeTextBox(app, name) {
var textArea = app
.createTextArea()
.setWidth("100%")
.setHeight("200px")
.setId(name)
.setName(name);
return textArea;
}
function exportAllSheets(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetsData = {};
for (var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
var rowsData = getRowsData_(sheet, getExportOptions(e));
var sheetName = sheet.getName();
sheetsData[sheetName] = rowsData;
}
var json = makeJSON_(sheetsData, getExportOptions(e));
displayText_(json);
}
function exportSheet(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rowsData = getRowsData_(sheet, getExportOptions(e));
var json = makeJSON_(rowsData, getExportOptions(e));
displayText_(json);
}
function getExportOptions(e) {
var options = {};
options.language = (e && e.parameter.language) || DEFAULT_LANGUAGE;
options.format = (e && e.parameter.format) || DEFAULT_FORMAT;
options.structure = (e && e.parameter.structure) || DEFAULT_STRUCTURE;
var cache = CacheService.getPublicCache();
cache.put("language", options.language);
cache.put("format", options.format);
cache.put("structure", options.structure);
Logger.log(options);
return options;
}
function makeJSON_(object, options) {
// START Array/Object addon
// Make arrays and objects in cells just like usual:
// ["array", "item", "one"] and {"objectItems" : ["array", "array2"] }
var obj, o;
for (var i = 0; i < object.length; i++) {
obj = object[i];
if (obj) {
for (prop in obj) {
o = obj[prop].toString();
if (
(o && (o.indexOf("{") == 0 && o.indexOf("}") == o.length - 1)) ||
(o.indexOf("[") == 0 && o.indexOf("]") == o.length - 1)
) {
object[i][prop] = JSON.parse(o);
}
}
}
}
//END Array/Object addon
if (options.format == FORMAT_PRETTY) {
var jsonString = JSON.stringify(object, null, 4);
} else if (options.format == FORMAT_MULTILINE) {
var jsonString = Utilities.jsonStringify(object);
jsonString = jsonString.replace(/},/gi, "},\n");
jsonString = prettyJSON.replace(/":\[{"/gi, '":\n[{"');
jsonString = prettyJSON.replace(/}\],/gi, "}],\n");
} else {
var jsonString = Utilities.jsonStringify(object);
}
if (options.language == LANGUAGE_PYTHON) {
// add unicode markers
jsonString = jsonString.replace(/"([a-zA-Z]*)":\s+"/gi, '"$1": u"');
}
return jsonString;
}
function displayText_(text) {
var output = HtmlService.createHtmlOutput(
"<textarea style='width:100%;' rows='20'>" + text + "</textarea>"
);
output.setWidth(400);
output.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(output, "Exported JSON (Replace any \"null\" instances with null (no quotes).");
}
// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - columnHeadersRowIndex: specifies the row number where the column names are stored.
// This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData_(sheet, options) {
var headersRange = sheet.getRange(
1,
1,
sheet.getFrozenRows(),
sheet.getMaxColumns()
);
var headers = headersRange.getValues()[0];
var dataRange = sheet.getRange(
sheet.getFrozenRows() + 1,
1,
sheet.getMaxRows(),
sheet.getMaxColumns()
);
var objects = getObjects_(dataRange.getValues(), normalizeHeaders_(headers));
if (options.structure == STRUCTURE_HASH) {
var objectsById = {};
objects.forEach(function(object) {
objectsById[object.id] = object;
});
return objectsById;
} else {
return objects;
}
}
// getColumnsData iterates column by column in the input range and returns an array of objects.
// Each object contains all the data for a given column, indexed by its normalized row name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// - rowHeadersColumnIndex: specifies the column number where the row names are stored.
// This argument is optional and it defaults to the column immediately left of the range;
// Returns an Array of objects.
function getColumnsData_(sheet, range, rowHeadersColumnIndex) {
rowHeadersColumnIndex = rowHeadersColumnIndex || range.getColumnIndex() - 1;
var headersTmp = sheet
.getRange(range.getRow(), rowHeadersColumnIndex, range.getNumRows(), 1)
.getValues();
var headers = normalizeHeaders_(arrayTranspose_(headersTmp)[0]);
return getObjects(arrayTranspose_(range.getValues()), headers);
}
// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
// - data: JavaScript 2d array
// - keys: Array of Strings that define the property names for the objects to create
function getObjects_(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty_(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
// Returns an Array of normalized Strings.
// Arguments:
// - headers: Array of Strings to normalize
function normalizeHeaders_(headers) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
var key = normalizeHeader_(headers[i]);
if (key.length > 0) {
keys.push(key);
}
}
return keys;
}
// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
// - header: string to normalize
// Examples:
// "First Name" -> "firstName"
// "Market Cap (millions) -> "marketCapMillions
// "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader_(header) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum_(letter)) {
continue;
}
if (key.length == 0 && isDigit_(letter)) {
continue; // first character must be a letter
}
if (upperCase) {
upperCase = false;
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty_(cellData) {
return typeof cellData == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise.
function isAlnum_(char) {
return (
(char >= "A" && char <= "Z") ||
(char >= "a" && char <= "z") ||
isDigit_(char)
);
}
// Returns true if the character char is a digit, false otherwise.
function isDigit_(char) {
return char >= "0" && char <= "9";
}
// Given a JavaScript 2d Array, this function returns the transposed table.
// Arguments:
// - data: JavaScript 2d Array
// Returns a JavaScript 2d Array
// Example: arrayTranspose([[1,2,3],[4,5,6]]) returns [[1,4],[2,5],[3,6]].
function arrayTranspose_(data) {
if (data.length == 0 || data[0].length == 0) {
return null;
}
var ret = [];
for (var i = 0; i < data[0].length; ++i) {
ret.push([]);
}
for (var i = 0; i < data.length; ++i) {
for (var j = 0; j < data[i].length; ++j) {
ret[j][i] = data[i][j];
}
}
return ret;
}
How do i create a multi-dimensional array from different javascript variables ?
For example, i have these three variables
var pdate = "|2019-12-26|2019-12-26|2019-12-26"
var products_id = "3354|5009|61927"
var products_category = "ENERGETICS|CASIO|SEIKO"
And i would like to transform them into this
var products_list = []
[0] = {pdate:"2019-12-26",products_id:"3354",products_category:"ENERGETICS"}
[1] = {pdate":"2019-12-26",products_id:"5009",products_category:"CASIO"}
[2] = {pdate:"2019-12-26",products_id:"61927",products_category:"SEIKO"}
Any ideas ?
Thanks
You can use the function split to separate the datas:
var pdate = "2019-12-26|2019-12-26|2019-12-26";
var products_id = "3354|5009|61927";
var products_category = "ENERGETICS|CASIO|SEIKO";
var arrayPdate = getData(pdate);
var arrayProducts_id = getData(products_id);
var arrayProducts_category = getData(products_category);
var result = []
for (let i = 0; i < arrayPdate.length; i++) {
let jsonObject = {
pdate: arrayPdate[i],
products_id: arrayProducts_id[i],
products_category: arrayProducts_category[i]
}
result.push(jsonObject)
}
console.log(result);
function getData(c) {
return c.split("|")
}
You need use .split function on your string and then use loop with array index for others.
var pdate = "2019-12-26|2019-12-26|2019-12-26";
var products_id = "3354|5009|61927";
var products_category = "ENERGETICS|CASIO|SEIKO";
pdate = pdate.split('|');
products_id = products_id.split('|');
products_category = products_category.split('|');
let arr = [];
for(let i=0; i<pdate.length; i++) {
arr.push({
pdate: pdate[i],
products_id: products_id[i],
products_category: products_category[i]
});
}
console.log(arr);
I'm starting with unit testing. I need to create some fake data to run the tests. So let's say inside a stubbed method I'm passing an obj as an argument and I do things with obj.obj1.obj2.data inside the function. Is there a way to set this fake object? So, given:
obj.obj1.obj2.data
It creates:
obj = {
obj1: {
obj2: {
data: 'whatever'}}}
So it would be at the end something like:
var obj = creator('obj.obj1.obj2.data', 20);
Assuming the string is only a set of objects (no arrays) this should be fairly straightforward. Just split the input string on . and then use a while loop to do the nesting.
function creator(str,val){
var tree = str.split('.');
var ret = {};
var cur = ret;
while(tree.length){
var name = tree.shift();
cur[name] = tree.length ? {} : val;
cur = cur[name];
}
return ret;
}
document.querySelector("#out").innerHTML = JSON.stringify(creator('obj.obj1.obj2.data',20));
<div id="out"></div>
Just in case anyone else in interested, I created a simple npm module with the function below (https://github.com/r01010010/zappy) check it out:
var objFrom = function(str, last_value){
var objs = str.split('.');
var r = {};
var last = r;
for(i=0; i < objs.length; i++) {
if(i !== objs.length - 1){
last = last[objs[i]] = {};
}else{
last[objs[i]] = last_value;
}
}
return r;
}
var obj = objFrom('obj1.obj2.data', 20);
console.log(obj.obj1.obj2.data);
I have this input sample:
var c1 = "s_A_3";
var c2 = "s_B_10";
var c3 = "s_B_9";
var c4 = "s_C_18";
var c5 = "s_C_19";
var c6 = "s_C_20";
Which can easily be concatenated to:
var keypairs = ["A_3","B_10","B_9","C_18","C_19","C_20"];
And I want to convert this to a multidimensional array like this:
var groupArray = [["A",[3]],["B",[10,9]],["C",[18,19,20]]];
It's like a kind of card-sorting. How can I achieve this?
Maybe something like this:
function makeGroups(arr) {
var result = [], prev;
for(var i = 0; i < arr.length; i++) {
var x = arr[i].split("_");
if (prev !== x[0]) {
prev = x[0];
result.push([prev, []]);
}
result[result.length - 1][1].push(x[1]); // or .push(parseInt(x[1], 10))
}
return result;
}
var keypairs = ["A_3","B_10","B_9","C_18","C_19","C_20"];
console.log(makeGroups(keypairs));
// [["A",["3"]],["B",["10","9"]],["C",["18","19","20"]]]
Demonstration
The above method assumes the groups will be contiguous (e.g. all B_ elements appear together). In case your input may be out of order, you can tweak this algorithm to still group all elements together regardless of where they appear in the input:
function makeGroups(arr) {
var result = [], keys = {};
for(var i = 0; i < arr.length; i++) {
var x = arr[i].split("_");
if (!(x[0] in keys)) {
keys[x[0]] = [];
result.push([x[0], keys[x[0]]]);
}
keys[x[0]].push(x[1]); // or .push(parseInt(x[1], 10))
}
return result;
}
var keypairs = ["A_3","B_10","C_18","C_19","C_20","B_9"];
console.log(makeGroups(keypairs));
// [["A",["3"]],["B",["10","9"]],["C",["18","19","20"]]]
Demonstration
When you need to mention "key value pairs" in a JS program, it's usually most appropriate to use... key value pairs =D.
function solution(input) {
var kvp = {},
result = [];
input.forEach(function (el) {
var cut = el.split("_"),
alpha = cut[0],
numeric = cut[1],
elsWithSameAlpha = kvp[alpha] = kvp[alpha] || [];
elsWithSameAlpha.push(numeric);
});
Object.keys(kvp).forEach(function (key) {
result.push([key, kvp[key]]);
});
return result;
}
Hi I have a very long list of key value pairs in json key:value, key:value and so on
car <--> wheel
wheel <--> tyre
bed <--> sheets
guitar <--> strings
guitar <--> pickup
tyre <--> rubber
What I want is to group all relations into arrays no matter how distant like this
[car, wheel, tyre, rubber]
[guitar, strings, pickup]
[bed, sheets]
What is an efficient way to do this with Javascript?
First of all, I would store the relationships as arrays so that you can have duplicate "keys." Key methods: an initial dictionary including every word related to each individual word; a recursive chain expander using map and reduce; filtering chains based on equivalency.
Array.prototype.getUnique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
var links = {};
var pairs = [
["car", "wheel"],
["wheel", "tyre"],
["bed", "sheets"],
["guitar", "strings"],
["guitar", "pickup"],
["rubber", "tyre"],
["truck", "wheel"],
["pickup", "car"]
];
pairs.map(function(pair) {
links[pair[0]] = links[pair[0]] || [];
links[pair[1]] = links[pair[1]] || [];
links[pair[0]].push(pair[1]);
links[pair[1]].push(pair[0]);
});
var append = function(list) {
var related = list.map(function(item) {
return links[item];
}).reduce(function(listA, listB) {
return listA.concat(listB);
}).filter(function(item) {
// make sure related only includes new links
return list.indexOf(item) == -1
}).getUnique();
return related.length ? append(list.concat(related)) : list.concat(related);
};
var branches = [];
for( var word in links ) {
branches.push(append(links[word].concat(word)));
}
var compareArrays = function(listA, listB) {
if( listA.length != listB.length ) return false;
return listA.map(function(element) {
if( listB.indexOf(element) == -1 ) return 0;
return 1;
}).filter(function(el) {
return el == 1;
}).length == listA.length;
};
var _branches = branches;
var chains = branches.filter(function(branch1, i) {
var isUnique = _branches.filter(function(branch2) {
// are they equivalent
return compareArrays(branch1, branch2);
}).length == 1;
delete _branches[i];
return isUnique;
});
I'd go with a map of words, linking the sets they are currently in. The map (a javascript object) with nearly O(1) runtime for accessing a key should help the performance. Start with the same format as proposed by #matt3141:
var pairs = [
["car", "wheel"],
["wheel", "tyre"],
["bed", "sheets"],
["guitar", "strings"],
["guitar", "pickup"],
["rubber", "tyre"],
["truck", "wheel"],
["pickup", "car"]
];
var setsByWord = {};
for (var i=0; i<pairs.length; i++) {
var pair = pairs[i];
if (pair[0] in setsByWord && pair[1] in setsByWord) {
// both words are already known
if (setsByWord[pair[0]] === setsByWord[pair[1]]) {
; // We're lucky, they are in the same set
} else {
// combine the two sets
var sets = [setsByWord[pair[0]], setsByWord[pair[1]]];
var larger = sets[1].length > sets[0].length ? sets[1] : sets[0],
smaller = sets[+(larger===sets[0])];
for (var j=0; j<smaller.length; j++)
setsByWord[smaller[j]] = larger;
Array.prototype.push.apply(larger, smaller);
}
} else {
// add the missing word to the existing set
// or create a new set
var set = setsByWord[pair[0]] || setsByWord[pair[1]] || [];
if (!(pair[0] in setsByWord)) {
set.push(pair[0]);
setsByWord[pair[0]] = set;
}
if (!(pair[1] in setsByWord)) {
set.push(pair[1]);
setsByWord[pair[1]] = set;
}
}
}
return setsByWord;
This will split your graph in its connected components (In the setsByWord object these component arrays are indexed by the nodes):
> var results = [];
> for (var word in setsByWord)
> if (results.indexOf(setsByWord[word])<0)
> results.push(setsByWord[word]);
> return results;
[
["car","wheel","tyre","rubber","truck","guitar","strings","pickup"],
["bed","sheets"]
]
If you have a directed graph, and want arrays of all successors by word, you could use this:
var pairs = […],
graph = pairs.reduce(function(map, pair) {
(map[pair[0]] || (map[pair[0]] = [])).push(pair[1]);
return map;
}, {});
var successors = {};
for (var word in graph) (function getSuccessors(word) {
if (word in successors)
return successors[word];
successors[word] = [true]; // some marker against circles
return successors[word] = word in graph
? [].concat.apply(graph[word], graph[word].map(getSuccessors))
: [];
})(word);
return successors;
If you are sure to have no circles in the graph and only want lists for the beginners of paths, you might add this:
var results = [];
for (var word in successors)
for (var i=0; word in successors && i<successors[word].length; i++)
delete successors[successors[word][i]];
for (var word in successors)
results.push([word].concat(successors[word]));
return results;
// becomes:
[
["bed","sheets"],
["guitar","strings","pickup","car","wheel","tyre"],
["rubber","tyre"],
["truck","wheel","tyre"]
]