Convert array of objects to array of arrays of strings - javascript

Suppose I have the following structure:
var obj = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
But I need to export this data to csv with the following output:
"1", "2", "3"
"1", "2", "3"
I've tried the following code, but it does not work:
var csvContent = "data:text/csv;charset=utf-8,";
Object.values = function (obj) {
var vals = [];
for( var key in obj ) {
if ( obj.hasOwnProperty(key) ) {
vals.push(obj[key]);
}
}
return vals;
}
Object.values(obj).forEach(function(infoArray, index) {
dataString = infoArray.join(",");
csvContent += index < obj.length ? dataString + "\n" : dataString;
});
var encodedUri = encodeURI(prepearedString);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Could you please help me with this issue.

It looks as if you're converting objects to a CSV file. It's important to note that objects are basically hash maps which means that the keys are not accessed in a predictable order. Also, some of your rows may be missing a value, which would cause holes in your resulting data.
What I would do is to first transform all the rows into columns (and default to null wherever a value is missing) so that you can predictably access the values for all known columns. Then you can output a CSV header with all known headers, followed by the values.
Here's an example:
var rows = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
var columns = {};
rows.forEach(function (row, index) {
for (var key in row) {
if (!columns[key]) {
// Set up nullified column.
var values = [];
for (var i = 0; i < rows.length; i++) {
values.push(null);
}
columns[key] = values;
}
// Store the value in the column.
columns[key][index] = row[key];
}
});
// Print the header.
var header = Object.keys(columns);
console.log(header.join(','));
// Print the rows.
for (var i = 0; i < rows.length; i++) {
var values = header.map(function (key) { return columns[key][i]; });
console.log(values.join(','));
}
This is the output you get in the console from the above code:
one,two,three
1,2,3
1,2,3

Below is the code to extract values and have multilined them, CSV format can be managed.
var obj = [{one: 1, two: 2, three: 3}, {one: 1, two: 2, three: 3}];
var output = [];
for( var key in obj ) {
for( var k in obj[key]){
output.push(obj[key][k])
}
output.push('\n')
}
alert(output.join(''))

Related

Separate an array with an integer and a string

I have the following array, which returns the values ​​as follows:
0: data: (2) [10000, "Vinil s/ pó"] name: "Janeiro"
I'm trying to split this way:
var series1 = series.split(",");
var series2 = series1[1] + "," + series1[2];
But it gives me the following error:
Uncaught TypeError: series.split is not a function
Code to generate the array
var series = [],
len = data.length,
i = 0;
for(i;i<len;i++){
series.push({
name: 'Janeiro',
data:[data[i][7], data[i][3]]
});
}
Link to draw the graph Link
You don't need to split anything, your data is already in separate entries in the array, at series[index].data[0] (the number) and series[index].data[1] (the string). So you can access those in a loop, for instance:
// (`i` is already declared in the OP's code)
for (i = 0; i < series.length; ++i) {
var num = series[i].data[0];
var str = series[i].data[1];
console.log(num, str);
}
Live Example:
var data = [
[,,,"Vinil s/ pó",,,,10000],
[,,,"Another value",,,,20000],
];
var series = [],
len = data.length,
i = 0;
for(i;i<len;i++){
series.push({
name: 'Janeiro',
data:[data[i][7], data[i][3]]
});
}
// Using each entry:
for (i = 0; i < series.length; ++i) {
var num = series[i].data[0];
var str = series[i].data[1];
console.log(num, str);
}
Or with ES2015+ language features (for-of, destructuring, and const):
// Using each entry
for (const {data: [num, str]} of series) {
console.log(num, str);
}
Live Example:
var data = [
[,,,"Vinil s/ pó",,,,10000],
[,,,"Another value",,,,20000],
];
var series = [],
len = data.length,
i = 0;
for(i;i<len;i++){
series.push({
name: 'Janeiro',
data:[data[i][7], data[i][3]]
});
}
// Using each entry
for (const {data: [num, str]} of series) {
console.log(num, str);
}
Series seems to be an array of objects, since split is a String method you cant use it on arrays nor objects.
Inside each object you have the key data which points to an array so you don't have to split it in the way you seem to be trying.
Just access series[index].data[innerArrIndex]

Javascript add properties with the same name to an object

var elements = document.getElementsByClassName("someClass");
var obj = {};
for (var i = 0; i < elements.length; i++){
obj.userId = elements[i].id
}
// output: obj = {userId: 1, userId: 2, userId: 3.....etc}
Is it possible in some way? Thanks.
keys in Object must be unique, you can try use Array, like this
var obj = [];
var data = {};
for (var i = 0; i < elements.length; i++) {
data = {
userId: elements[i].id
};
obj.push(data);
}
// [ {userId: 1}, {userId: 2} ... ]
The JSON RFC says "the names within an object SHOULD be unique" - see here for more info however should your object have a duplicate key the last occurrence will be used.
An array would be a better solution for your data.

browse a table and share it on 2 tables in javascript

I have a table that follows a defined sequence that Repite : [ col , name , value1, value2 , value 3, col, name value1, value2, value3 ..col , name , value1, value2 , value 3 ]
code:
var data =["DN","Atac","1","2","3","PDA","Atac","5","6","7","EPDA","Atac","8","9","11","DN Potentielle","Atac","14","4","8"] ;
I try to split the data table col , name , values:
Code result :
var column = ["DN","PDA","EPDA","DN Potentielle"];
var name ="Atac";
var values =[ "1","2","3","5","6","7","8","9","11","14","4","8"];
how has the simplest method without a lot of code to do it
If you're sure that your data is consistent and can rely on the structure you wrote, the simplest thing would be:
var column = [];
var name = [];
var values = [];
for (var i = 0; i < data.length; i = i+5) {
column.push(data[i]);
name.push(data[i+1]);
values.push(data[i+2]);
values.push(data[i+3]);
values.push(data[i+4]);
};
name = name.filter(function(value, index, self) {
return self.indexOf(value) === index;
});
console.log(column); //["DN","PDA","EPDA","DN Potentielle"]
console.log(name); //["Atac"]
console.log(values); //["1", "2", "3", "5", "6", "7", "8", "9", "11", "14", "4", "8"]
Fiddle
Set up an object to hold the values:
var obj = { column: [], name: null, values: [] };
Then cycle over the array in groups of 5, adding the various elements to the object:
for (var i = 0, l = data.length; i < l; i+=5) {
obj.column.push(data[i]);
obj.name = data[i + 1];
// push.apply is a neat way of concatenation that doesn't
// require the creation of a new variable
obj.values.push.apply(obj.values, data.slice(i + 2, i + 5));
}
DEMO
I try to figure out what you want, and the best way is to retrieve the number value and string value without spliting it.
var data =["DN","Atac","1","2","3","PDA","Atac","5","6","7","EPDA","Atac","8","9","11","DN Potentielle","Atac","14","4","8"] ;
var columns = [];
var values = [];
$.each(data, function(k, v) {
var parsedValue = parseInt(data[k]);
if ( ! isNaN(parsedValue) ) {
values.push(parsedValue);
} else {
columns.push(v);
}
});
console.log(columns);
console.log(values);
Demo: http://jsfiddle.net/bzryqs84/1/

Setting up a variable length two-dimensional array

I have a string as follows :
Panther^Pink,Green,Yellow|Dog^Hot,Top
This string means I have 2 main blocks(separated by a '|') :
"Panther" and "Dog"
Under these two main blocks, I have, lets say "subcategories".
I wanted to create a 2-dimensional array represented (in logic) as follows :
Panther(Array 1) => Pink(Element 1),Green(Element 2), Yellow(Element 3)
Dog(Array 2) => Hot(Element 1), Top(Element 2)
Also,I want to be able to add a main block, lets say "Cat" with possible categories "Cute,Proud" to the two dimensional array
I've managed to get an Array containing "Panther^Pink,Green,Yellow" and "Dog^Hot,Top" by using JavaScript's split function.
Note that this string is received via Ajax and can be of any length, though the format shown above is always used.
----------------------------- EDIT ----------------------------
Ok, my script so far is :
$(document).ready(function(){
appFunc.setNoOfAppBlock('Panther^Pink,Green,Yellow|Dog^Hot,Top');
appFunc.alertPing();
});
var appFunc = (function(stringWithSeper) {
var result = {},
i,
categories = new Array(),
subcategories;
return {
setNoOfAppBlock: function(stringWithSeper){
categories = stringWithSeper.split("|");
for (i = 0; i < categories.length; i++) {
subcategories = categories[i].split("^");
result[subcategories[0]] = subcategories[1].split(",");
}
},
alertPing: function(){
alert(result["Panther"][1]);
}
};
})();
However, the function "alertPing" isn't "alerting" anything.What am am I doing wrong ?
To me the most logical representation of your data:
Panther^Pink,Green,Yellow|Dog^Hot,Top
Is with a JavaScript object with a property for each category, each of which is an array with the subcategories:
var data = {
Panther : ["Pink", "Green", "Yellow"],
Dog : ["Hot", "Top"]
}
You would then access that by saying, e.g., data["Dog"][1] (gives "Top").
If that format is acceptable to you then you could parse it as follows:
function parseData(data) {
var result = {},
i,
categories = data.split("|"),
subcategories;
for (i = 0; i < categories.length; i++) {
subcategories = categories[i].split("^");
result[subcategories[0]] = subcategories[1].split(",");
}
return result;
}
var str = "Panther^Pink,Green,Yellow|Dog^Hot,Top";
var data = parseData(str);
Assuming you're trying to parse your data into something like this:
var result = {
Panther: ["Pink", "Green", "Yellow"],
Dog: ["Hot", "Top"]
}
you can use string.split() to break up your string into subarrays:
var str = "Panther^Pink,Green,Yellow|Dog^Hot,Top";
var result = {}, temp;
var blocks = str.split("|");
for (var i = 0; i < blocks.length; i++) {
temp = blocks[i].split("^");
result[temp[0]] = temp[1].split(",");
}
Data can then be added to that data structure like this:
result["Cat"] = ["Cute", "Proud"];
Data can be read from that data structure like this:
var dogItems = result["Dog"]; // gives you an array ["Hot", "Top"]
You can use something like:
function parseInput(_input) {
var output = [];
var parts = _input.split('|');
var part;
for(var i=0; i<parts.length; i++) {
part = parts[i].split('^');
output[part[0]] = part[1].split(',');
}
return output;
}
Calling parseInput('Panther^Pink,Green,Yellow|Dog^Hot,Top'); will return:
output [
"Panther" => [ "Pink", "Green", "Yellow" ],
"Dog" => [ "Hot", "Top" ]
]
To add another item to the list, you can use:
output["Cat"] = ["Cute", "Proud"];

Find duplicates without going through the list twice?

I need to know if one or more duplicates exist in a list. Is there a way to do this without travelling through the list more than once?
Thanks guys for the suggestions. I ended up using this because it was the simplest to implement:
var names = [];
var namesLen = names.length;
for (i=0; i<namesLen; i++) {
for (x=0; x<namesLen; x++) {
if (names[i] === names[x] && (i !== x)) {alert('dupe')}
}
}
Well the usual way to do that would be to put each item in a hashmap dictionary and you could check if it was already inserted. If your list is of objects they you would have to create your own hash function on the object as you would know what makes each one unique. Check out the answer to this question.
JavaScript Hashmap Equivalent
This method uses an object as a lookup table to keep track of how many and which dups were found. It then returns an object with each dup and the dup count.
function findDups(list) {
var uniques = {}, val;
var dups = {};
for (var i = 0, len = list.length; i < len; i++) {
val = list[i];
if (val in uniques) {
uniques[val]++;
dups[val] = uniques[val];
} else {
uniques[val] = 1;
}
}
return(dups);
}
var data = [1,2,3,4,5,2,3,2,6,8,9,9];
findDups(data); // returns {2: 3, 3: 2, 9: 2}
var data2 = [1,2,3,4,5,6,7,8,9];
findDups(data2); // returns {}
var data3 = [1,1,1,1,1,2,3,4];
findDups(data3); // returns {1: 5}
Since we now have ES6 available with the built-in Map object, here's a version of findDups() that uses the Map object:
function findDups(list) {
const uniques = new Set(); // set of items found
const dups = new Map(); // count of items that have dups
for (let val of list) {
if (uniques.has(val)) {
let cnt = dups.get(val) || 1;
dups.set(val, ++cnt);
} else {
uniques.add(val);
}
}
return dups;
}
var data = [1,2,3,4,5,2,3,2,6,8,9,9];
log(findDups(data)); // returns {2 => 3, 3 => 2, 9 => 2}
var data2 = [1,2,3,4,5,6,7,8,9];
log(findDups(data2)); // returns empty map
var data3 = [1,1,1,1,1,2,3,4];
log(findDups(data3)); // returns {1 => 5}
// display resulting Map object (only used for debugging display in snippet)
function log(map) {
let output = [];
for (let [key, value] of map) {
output.push(key + " => " + value);
}
let div = document.createElement("div");
div.innerHTML = "{" + output.join(", ") + "}";
document.body.appendChild(div);
}
If your strings are in an array (A) you can use A.some-
it will return true and quit as soon as it finds a duplicate,
or return false if it has checked them all without any duplicates.
has_duplicates= A.some(function(itm){
return A.indexOf(itm)===A.lastIndexOf(itm);
});
If your list was just words or phrases, you could put them into an associative array.
var list=new Array("foo", "bar", "foobar", "foo", "bar");
var newlist= new Array();
for(i in list){
if(newlist[list[i]])
newlist[list[i]]++;
else
newlist[list[i]]=1;
}
Your final array should look like this:
"foo"=>2, "bar"=>2, "foobar"=>1

Categories

Resources