I have a input array of objects
[
{ col1: 'col1value1', col2: 'col2value1', col3: col1value3},
{ col1: 'col1value2', col2: 'col2value2', col3: col1value2}
]
Now I want to convert this into a object two arrays like below
columns:["col1" , "col2","col3"],
data: ["col1value1","col2value1" , "col1value3"] ,
["col1value2","col2value2" , "col1value2"]
is there any good way or faster way . as I am trying to use 2 foreach loop on all the values and creating columns and data array
Use Object.keys() method to get all the columns and use Array.prototype.map method to traverse the array and get the values using Object.values() method.
const input = [
{ col1: 'col1value1', col2: 'col2value1', col3: 'col1value3' },
{ col1: 'col1value2', col2: 'col2value2', col3: 'col1value2' },
];
const columns = Object.keys(input[0]);
const data = input.map((x) => Object.values(x));
console.log(columns);
console.log(data);
Related
I have 2 arrays:
[{ Name: ‘Bart’, col2: +4, col3:4},
{ Name: ‘Marge’, col2: +8, col3:},
{ Name: ‘Bart’, col2: -3 , col3:8},
{ Name: ‘Homer’, col2: +12, col3:4},
{ Name: ‘Bart’, col2: +12, col3:2},
{ Name: ‘Homer’, col2: +2, col3:13}]
and
[{ Name: ‘Bart’, col2:4},
{ Name: ‘Marge’, col2:12},
{ Name: ‘Bart’, col2:4},
{ Name: ‘Bart’, col2:4},
{ Name: ‘Homer’, col2:4}]
I want the update the contents from col3 in array1 with the contents from col2 in array2. Col2 in array2 contains multiple times the correct values (the same ones for each name) and I want to update col3 in array1 with these values.
I know how to do this in Python but I'm completely lost in javascript.
*** edit
I tried this:
array1.forEach((x) => {
const bla = array2.find((y) => y.Name === x.Name);
x.col3 = bla.col2;
});
and it is in the last part that I got stuck ... How to update (replace) the value with another one.
I know, data is a bit weird, I'm trying to make one array (or object) of 3 different ones. And yes, the values in array2/col2 are the same for 'Bart', 'Marge',... but in array1 they are a bit random.
I am trying to find the best way to store in Redux a 2D array with row and column names.
In terms of priorities, I would rank code readability and maintainability above performance. Hence, accessing a value through table[row][col] would be preferable.
I have thought about two solutions:
First, storing it in three distinct variables colNames, rowNames and table. Accessing values would still be doable. But, for example, removing a column would then require to modify both colNames and rowNames. Incrementing some value from row and column names would require to access all three variables.
var rowNames = ["row1", "row2", "row3"];
var colNames = ["col1", "col2", "col3"];
var table = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
The other way would be to store a single variable table as an Object. It becomes easy to access values. But it is harder to correctly update it in Redux to respect immutable state.
var table = {
row1: {
col1: 1,
col2: 2,
col3: 3
},
row2: {
col1: 4,
col2: 5,
col3: 6
},
row3: {
col1: 7,
col2: 8,
col3: 9
}
};
Some other idea would be to use Immer JS with the second solution to improve code readability.
What is then the best way to store such a value in Redux ?
Solution I chose
I ended up using the second solution with a single variable. Once the modification of this table is properly made in Redux reducers, it makes accessing and displaying said table easy.
I do think your solution is quite nice and adapted to rendering in an html table. However you will have to iterate over Object.keys(table) to go through the rows.
Another solution could be to do somehing like that so you can iterate over objects directly:
var table = [
{
name: "row1",
col1: 1,
col2: 2,
col3: 3
},
{
name: "row2",
col1: 4,
col2: 5,
col3: 6
},
{
name: "row3",
col1: 7,
col2: 8,
col3: 9
}
];
This solution also has it's problems: you have to specifically take the name property out of the object while iterating for rows. You would also have to iterate over Object.keys of the inner object avoiding the treatment of the "name" column.
Hope this help as an overview of your problem :)
I am working on a code optimization where I have several rows (~500-1000) of data with at least 300 columns.
The data is stored as an array of objects:
data = [
{col1: 1, col2: 2, col3: null, col4: 1.3, col5:undefined, col6: 2, ....},
{col1: 3, col2: 4, col3: 3, col4: 1.1, col5:8, col6: 2, ....},
.
.
.
{col1: 1.1, col2: 1.2, col3: 7, col4: 3, col5:4, col6: 2, ....}
]
Then I have another array of objects named calculators, these are user-defined calculations. These calculations can have another calculated variable like 2nd object in the following array.
So I need to maintain the order.
calculators = [
{formula:'col1 + sin(col2)', order:0, colname: 'calc1'}
{formula:'calc1 * col6', order:1, colname: 'calc2'}
.
.
.
{formula: 'any random calculation', order:n, colname:'RandomName'}
]
my current code-flow is,
Extraction of dependent columns from calculators, like col1 and col2
for calc1 and col6 from calc2.
dependentCols = [col1, col2, col6]
Looping through the data array with nested for loops for calculators and columns and setting the value in parser for each
dependent column. parser.set(column, row[column]);
Then formula evaluation and appending that value to the dararow.
The original code I have includes some other stuff to handle sub-columns, units, and other stuff. That's why instead of pasting the original code, here is the rough draft.
const parser = math.parser();
data = _.map(data, row=>{
row = {...row};
_.forEach(calculators, (calculator)=>{
_.forEach(dependentCols, col=>{
// cannot add the whole row as it is because of the sub-column stuff.
parser.set(col, row[col]);
});
try {
const value = parser.eval(calculator.formula);
row[colname] = value;
} catch (exception) {
console.warn(parser, exception, calculator.colname);
}
}
});
return row;
});
}
The original code is definitely working (for a year). Its just very slow, with 450 rows and 20 calculations its taking upto 12 seconds.
So instead of going row by row and effectively cell by cell I am thinking about passing the whole column at the same time to the eval function. But I couldn't find any supporting documentation.
Any help will be appreciated.
I'm new to javascript and need to create a web app where a user will click a button, and the array of data will export into a shape file. After reading this answer I know that it is possible with an ARCGIS server, but I do not have access to this.
The array in question is a stream of data similar to the following
var array = [
[17, 70, "mark", "let", "test", "test"],
[18, 50, "marj", "get", "test", "test"],
ETC...]
I've also read about shp-write but I don't know where to start. Would anyone be able to give me any examples of how to do this, or pointers where to start? Thanks.
You should just convert your data from a simple array to an array of points and an array of features, like:
let points = [
[17, 70],
[18, 50],
...
];
let features = [
{col1: "mark", col2: "let", col3: "test", col4: "test"},
{col1: "marj", col2: "get", col3: "test", col4: "test"},
...
];
And then call the write function provided by scp-write, providing your callback function to write the resulting file (check the examples for the callback function).
let scp = require('scp-write');
scp.write(features, 'POINT', points, callbackFunction);
I’m looking for a compact lodash solution to take an array of objects and then create a new object with the keys of the objects in the array and the unique values for each key.
[
{
color: "black",
type: "bag",
},
{
color: "red",
type: "pants",
},
{
color: "black",
type: "jacket",
},
]
Desired output:
{
color: ["black", "red"],
type: ["bag", "pants", "jacket"],
}
Thanks!
You can solve this using lodash#flatMap with a lodash#toPairs iteratee, to create a flattened version of an array pair of keys and values. Use lodash#groupBy with an iteratee function that removes the key of the array pairs, Array#shift, and use such value as the grouping key for the collection. Lastly, use lodash#mapValues with an iteratee that is composed of lodash#flatten and lodash#uniq, to flatten the array and only get the unique values for each grouped array. Note that the function composition uses lodash#flow to compose successive function arguments to form one functional result.
var result = _(array)
.flatMap(_.toPairs)
.groupBy(v => v.shift())
.mapValues(_.flow(_.flatten, _.uniq))
.value();
var array = [
{
color: "black",
type: "bag",
},
{
color: "red",
type: "pants",
},
{
color: "black",
type: "jacket",
}
];
var result = _(array)
.flatMap(_.toPairs)
.groupBy(v => v.shift())
.mapValues(_.flow(_.flatten, _.uniq))
.value();
console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
I can't see a function that'll do this for you, so here's a solution that solves the problem in a number of straightforward steps using only lodash functions.
const listOfPairs = _.flatten(_.map(input, _.toPairs))
transforms the list of objects into a list of pairs of [key, value]
listOfPairs = [
[ 'color', 'black' ],
[ 'type', 'bag' ],
[ 'color', 'red' ],
[ 'type', 'pants' ] ]
now, we can group these up by the values in the first position in each pair.
const indexByKeyToValues = _.toPairs(_.groupBy(listOfPairs, _.head))
which gives us
indexByKeyToValues = [
[ 'color', [ ['color', 'black'], ['color', 'red'] ] ],
[ 'type', [ ['type', 'bag'], ['type', 'pants'] ] ] ]
then, map over the value arrays to pick the last element (the original values in the input maps)
const pairsOfKeyAndValue = _.map(indexByKeyToValues, ([k, vs]) => [k, _.map(vs, _.last)])
which is almost there
pairsOfKeyAndValue = [
[ 'color', [ 'black', 'red' ] ],
[ 'type', [ 'bag', 'pants' ] ] ]
we just need to rebuild an object using these pairs
const result = _.fromPairs(pairsOfKeyAndValue)
The whole "transforming a map to and from sequences of pairs" trick is really common in functional programming to do this kind of processing. Once you've done that, figuring out the rest of the steps isn't too tricky.
Hopefully this gives you a general idea you can use to solve these kinds of problems in future.
Use what's built-in. It's faster, shorter, and easier to reason from.
const arr = [{color: "black",type: "bag",},{color: "red",type: "pants",},{color: "black",type:"jacket",}],
obj = arr.reduce((h, y) => {
Object.keys(y).forEach(k => {
if (!h[k]) {
h[k] = []
h[k].push(y[k])
} else if (!h[k].includes(y[k])) h[k].push(y[k])
})
return h
}, {})
console.log(obj)