Related
I have been trying to convert this data:
var myArray = [
[1,2,3,4],
["1","2","3","4"],
["a", "b", "c", "d"]
]
to this:
var result = [
{
"num": 1,
"str": "1",
"let": "a"
},
{
"num": 2,
"str": "2",
"let": "b"
},
{
"num": 3,
"str": "3",
"let": "c"
},
{
"num": 4,
"str": "4",
"let": "d"
}
]
Any assistance will be extremely helpful. I have tried various iterations but none of them yield what I am hoping for.
I am trying to use this:
objectified_data = array_data.map(function(x) {
return {
"num": x[0],
"str": x[1],
"let": x[2]
}
})
But I cannot figure out how to make the homogenous set of array, heterogenous for this to work. Ultimately, I am trying to filter out certain keys, so the original data as it was is not working for that task
You can achieve this with a simple for
var myArray = [
[1, 2, 3, 4],
["1", "2", "3", "4"],
["a", "b", "c", "d"]
]
const json = [];
for (let i = 0; i < myArray[0].length; i++) {
json.push({
num: myArray[0][i],
let: myArray[1][i],
str: myArray[2][i],
});
}
console.log(json);
Try this
var myArray = [[1,2,3,4],["1","2","3","4"],["a", "b", "c", "d"]];
let result = myArray[0].map((v, i) => ({
"num": myArray[0][i],
"let": myArray[1][i],
"str": myArray[2][i]
}))
console.log(result)
Just a basic solution. You would want i to be dynamic I believe ? In that case you can just check the first nested array's size and use that as i.
let x = 0;
let y = 1;
let z = 2;
let json = [];
for(let i=0; i<4;i++){
let item = {};
item = {
["num"]: myArray[x][i],
["let"]: myArray[y][i],
["str"]: myArray[z][i]
}
result.push(item);
}
I've this object:
const dataset = {
"2019": {
"a": 1,
"b": 2,
"c": 3,
"d": 4
},
"2020": {
"a": 2,
"b": 4,
"c": 6,
"d": 8
},
"2021": {
"a": 10,
"b": 11,
"c": 12,
"d": 13
}
}
I would like to obtain these two objects:
const obj1 = {
"2019": {
"a": 1,
"c": 3,
},
"2020": {
"a": 2,
"c": 6,
},
"2021": {
"a": 10,
"c": 12,
}
}
const obj2 = {
"2019": {
"b": 2,
"d": 4
},
"2020": {
"b": 4,
"d": 8
},
"2021": {
"b": 11,
"d": 13
}
}
So "split" the object in two objects based on some keys of the inner objects.
Here is what I tried:
function pickKeys(dataObj, keys) {
return Object.entries(dataObj).map(([d, obj]) => {
return { [d]: _.pick(obj, keys) }
})
}
const obj1 = pickKeys(dataset, ['a', 'c'])
The result is:
const obj1 = [
{ '2019': { a: 1, c: 3 } },
{ '2020': { a: 2, c: 6 } },
{ '2021': { a: 10, c: 12 } }
]
So almost there but it's not perfect. Which is the better way to do that?
You do this using combination of map, reduce methods and one for...in loop that will turn array of keys into array of objects. Then you can use array destructuring to get two separate objects.
const dataset = {"2019":{"a":1,"b":2,"c":3,"d":4},"2020":{"a":2,"b":4,"c":6,"d":8},"2021":{"a":10,"b":11,"c":12,"d":13}}
const [a, b] = [['a', 'c'], ['b', 'd']]
.map(keys => keys.reduce((r, key) => {
for (let year in dataset) {
if (!r[year]) r[year] = {}
r[year][key] = dataset[year][key]
}
return r;
}, {}))
console.log(a)
console.log(b)
The problem is that map returns an array with replaced elements, while you want an object.
Since you are already using Lodash you could use mapValues to transform the values of an object and return an object instead of an array.
function pickKeys(dataObj, keys) {
return _.mapValues(dataObj, obj => _.pick(obj, keys));
}
function pickKeys(dataObj, keys) {
return _.mapValues(dataObj, obj => _.pick(obj, keys));
}
const dataset = {
"2019": {
"a": 1,
"b": 2,
"c": 3,
"d": 4
},
"2020": {
"a": 2,
"b": 4,
"c": 6,
"d": 8
},
"2021": {
"a": 10,
"b": 11,
"c": 12,
"d": 13
}
}
console.log(pickKeys(dataset, ["a", "c"]));
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.15/lodash.min.js"></script>
You could map the wanted keys by using the entries of the given object.
const
dataset = { 2019: { a: 1, b: 2, c: 3, d: 4 }, 2020: { a: 2, b: 4, c: 6, d: 8 }, 2021: { a: 10, b: 11, c: 12, d: 13 } },
groups = [['a', 'c'], ['b', 'd']],
[result1, result2] = Object
.entries(dataset)
.reduce((r, [k, o]) =>
groups.map((group, i) =>
group.reduce(
(q, g) => ({ ...q, [k]: { ...q[k], [g]: o[g] } }),
r[i] || {}
)
),
[]
);
console.log(result1);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
The next provided example code is reduce based, generic but configurable in its usage ...
function createAndCollectSubdata(collector, dataEntry) {
const { keyLists, subdataList } = collector;
const [ dataKey, dataValue ] = dataEntry;
keyLists.forEach((keyList, idx) => {
const data = subdataList[idx] || (subdataList[idx] = {});
const subdata = data[dataKey] || (data[dataKey] = {}) ;
keyList.forEach(key => subdata[key] = dataValue[key]);
});
return collector;
}
const dataset = {
"2019": {
"a": 1,
"b": 2,
"c": 3,
"d": 4
},
"2020": {
"a": 2,
"b": 4,
"c": 6,
"d": 8
},
"2021": {
"a": 10,
"b": 11,
"c": 12,
"d": 13
}
};
const [
acSubdata,
bdSubdata
] = Object.entries(dataset).reduce(createAndCollectSubdata, {
keyLists: [["a", "c"], ["b", "d"]],
subdataList: []
}).subdataList;
console.log('acSubdata :', acSubdata);
console.log('bdSubdata :', bdSubdata);
.as-console-wrapper { min-height: 100%!important; top: 0; }
I have an array of an object with dynamic keys
response = [{"1": 1}, {"2": 1}, {"3": 1}, {"4": 0}, {"5": 0}];
I want to flatten this array of an object into a single array
Output = [1, 1, 1, 0, 0]
I tried the following:
const test2 = this.response.map(obj => {
Object.keys(obj).map(function(key){
return obj[key]
})
});
const test = this.response.reduce(function(prev, curr){
console.log(curr)
return (curr) ? prev.concat(curr): prev;
},[]);
You can just use map and object.values
response = [{"1": 1}, {"2": 1}, {"3": 1}, {"4": 0}, {"5": 0}]
const vals = response.map(o => Object.values(o)[0])
console.log(vals)
You can use .map() with .concat():
let data = [{"1": 1}, {"2": 1}, {"3": 1}, {"4": 0}, {"5": 0}];
let result = [].concat(...data.map(Object.values));
console.log(result);
Use reduce and for..in to loop over the object
let response = [{
"1": 1
},
{
"2": 1
},
{
"3": 1
},
{
"4": 0
},
{
"5": 0
}
]
let k = response.reduce(function(acc, curr) {
for (let keys in curr) {
acc.push(curr[keys])
}
return acc;
}, [])
console.log(k)
response = [{"1": 1},{"2": 1},{"3": 1},{"4": 0},{"5": 0}]
var newArray = []
for (element of response) {
Object.keys(element).map(key => {
newArray.push(element[key])
})
}
console.log(newArray)
I want to merge 2 object with same key, value from 2 array, something like this:
var arr1 = [
{ a: "a", 1: 1, 2: 2 },
{ a: "b", 1: 1, 2: 3 }
];
var arr2 = [
{ a: "a", 3: 123 },
{ a: "b", 3: 4411 }
];
var arr3 = _.map(arr1, function(a1) {
var a3 = {};
_.map(arr2, function(a2) {
if (a1.a == a2.a) {
a3 = _.extend(a1, a2);
}
})
return a3
});
result:
arr3 = [
{ '1': 1, '2': 2, '3': 123, a: 'a' },
{ '1': 1, '2': 3, '3': 4411, a: 'b' }
]
Does it look stupid? Are there any others ways to do this?
Thanks for reading.
Use a lodash chain to concat the arrays, group similar objects, and then merge each group to a single object:
var arr1 = [{ a: "a", 1: 1, 2: 2 }, { a: "b", 1: 1, 2: 3 }];
var arr2 = [{ a: "a", 3: 123 }, { a: "b", 3: 4411 }];
var result = _(arr1)
.concat(arr2) // concat the 2nd array
.groupBy('a') // group by the identical key
.map(_.spread(_.curry(_.merge, {}))) // left currey merge to to create a new empty object, and spread the group as parameters
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
With ES6 you can use Array#reduce to collect the similar objects in a Map, then get the Map#values iterator, and use the spread syntax to convert to an array:
const arr1 = [{ a: "a", 1: 1, 2: 2 }, { a: "b", 1: 1, 2: 3 }];
const arr2 = [{ a: "a", 3: 123 }, { a: "b", 3: 4411 }];
const result = [...arr1.concat(arr2) // concat the arrays
.reduce((m, o) => m.set(o.a, Object.assign(m.get(o.a) || {}, o)), // use a map to collect similar objects
new Map()
).values()]; // get the values iterator of the map, and spread into a new array
console.log(result);
you can do
var arr1 = [
{ a: "a", 1: 1, 2: 2 },
{ a: "b", 1: 1, 2: 3 }
];
var arr2 = [
{ a: "a", 3: 123 },
{ a: "b", 3: 4411 }
];
let result = arr1.map((e) => {
for(let element of arr2){
if(e.a == element.a) Object.assign(e, element);
}
return e;
});
console.log(result);
If I have an array of objects and one object in JavaScript:
var data = [{"a": 1, "b": 2}, {"a": 1}, {"a": 1, "b": 2, "c": 3}];
var myFilter = {"a": 1, "b": 2};
...and would like to use myFilter object as a filter to the array of objects to create a new array of objects if and only if the object at least matches or contain the myFilter key/value pairs.
Any recommendation how can I go ahead and put it into code? I need to create a new array that was filtered from data using the myFilter key/value pair.
I was able to do this but myFilter only contains 1 key/value pair.
My expected new array is:
var newArr = [];
newArr = [{"a": 1, "b": 2}, {"a": 1, "b": 2, "c": 3}];
You can use arr.filter(callback[, thisArg]) for this:
var data = [{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 3 }]
var myFilter = { "a": 1, "b": 2 }
var myFilterFunction = function(obj) {
for (var p in myFilter) {
if (obj[p] !== myFilter[p]) return false
}
return true
}
var newArr = data.filter(myFilterFunction)
document.write(JSON.stringify(newArr))
A more universal approach would be this filterFuncByObj(filterObj) function, wich takes any custom filter object:
data.filter(filterFuncByObj(myFilter)):
var data = [{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 3 }]
var myFilter = { "a": 1, "b": 2 }
var newArr = data.filter(filterFuncByObj(myFilter))
// Demo Output
document.write(JSON.stringify(newArr))
function filterFuncByObj(filterObj) {
return function(obj) {
for (var p in filterObj) {
if (obj[p] !== filterObj[p]) return false
}
return true
}
}
Using Array.filter(), Object.keys() and Array.every() this could be one way to go
var data = [{"a": 1, "b": 2}, {"a": 1}, {"a": 1, "b": 2, "c": 3}];
var myFilter = {"a": 1, "b": 2};
var filteredData = data.filter(function(d) {
return Object.keys(myFilter).every(function(f) {
return d[f] === myFilter[f];
})
});
console.log(JSON.stringify(filteredData));
The lodash way, just in case:
var data = [{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 3 }];
var myFilter = { "a": 1, "b": 2 };
var newArr = _.filter(data, myFilter);
document.write(JSON.stringify(newArr, null, 3));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>