I have two arrays:
The first contains unique names of fields in a nested array:
[0][0]:Name1
[0][1]:Name2
[0][2]:Name3
etc.
The second contains multiple items with values in a nested array like this:
[0][0] XYZ
[0][1] XYZA
[0][2] XYZ2
[1][0] XYZaa
[1][1] XYZas
[1][2] XYA
etc
What I want to do is to merge it and name it in this way:
[0] Name1: XYZ
[0] Name2: XYZA
[0] Name3: XYZ2
[1] Name1: XYZaa
[1] Name2: XYZas
[1] Name3: XYA
To achieve this I first attempted the following:
var mergedArr = name.concat(data);
That works fine, however I believe I can also use lodash to get closer to what I want:
_.merge(name, data)
and should work fine too.
I was trying to name it by using
_.zipObject
Yet it doesn't work the way I would like
I was trying few options with zip, zipObject, yet non of it gave me expected output.
Edit1:
how I created arrays:
$("#T1020 tr").each(function(x, z){
name[x] = [];
$(this).children('th').each(function(xx, zz){
name[x][xx] = $(this).text();
});
})
$("#T1020 tr").each(function(i, v){
data[i] = [];
$(this).children('td').each(function(ii, vv){
data[i][ii] = $(this).text();
});
})
If I understand your question correctly, you're wanting to zip array1 and array2 into a single array where:
each item of the result array is an object
the keys of each object are values of array1[0], and
the values of each key corresponding nested array of array2
To produce the following:
[
{
"name1": "xyz",
"name2": "xyza",
"name3": "xyz2"
},
{
"name1": "xyzaa",
"name2": "xyzas",
"name3": "xya"
}
]
This can be achieved without lodash; first map each item of array2 by a function where array1[0] is reduced to an object. The reduced object is composed by a key that is the current reduce item, and a value that is taken from the indexed value of the current map item:
const array1 = [
['name1', 'name2', 'name3']
]
const array2 = [
['xyz', 'xyza', 'xyz2'],
['xyzaa', 'xyzas', 'xya']
]
const result = array2.map((item) => {
/* Reduce items of array1[0] to an object
that corresponds to current item of array2 */
return array1[0].reduce((obj, value, index) => {
return { ...obj,
[value]: item[index]
};
}, {});
});
console.log(JSON.stringify(result, null, ' '));
Iterate the values (your array2) and take the sub-array from the keys (array) using the current index and the % operator. This will ensure that if that the keys are taken in a cyclic way (see example with keys2 and values2). Convert to object with _.zipObject:
const fn = (keys, values) => values.map((v, i) => _.zipObject(keys[i % keys.length], v))
const keys1 = [['name1', 'name2', 'name3']]
const values1 = [['xyz', 'xyza', 'xyz2'], ['xyzaa', 'xyzas', 'xya']]
const keys2 = [['name1', 'name2', 'name3'], ['name11', 'name12', 'name13']]
const values2 = [['xyz', 'xyza', 'xyz2'], ['xyzaa', 'xyzas', 'xya'], ['abc', 'def', 'hij']]
console.log(fn(keys1, values1))
console.log(fn(keys2, values2))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Related
I have a Keys Array and Multiple Values Array . I want push values array into keys Array .
Example :-
data[0] :['ktCalender', 'presenter', 'emailId', 'topic', 'status'] // Keys
[1] : ['2022-05-05', 'abc', 'abc#gmail.com', 'cricket overview', 'sheduled'] // Values
[3]: ['2022-05-04', 'xyz', 'xyz#gmail.com', 'ApS', 'organized']. // Values
I want Answer like : [
{ktCalender:2022-05-05,presenter:'abc',emailId:'abc#gmail.com',topic:'cricket overview',status:'sheduled'},
ktCalender:'2022-05-04',presenter:'xyx',emailId:'xyz#gmail.com',topic:'APS',status:'organized'},
]
let data = ['ktCalender', 'presenter', 'emailId', 'topic', 'status'];
let Values = [];
Values[0] = ['2022-05-04', 'xyz', 'xyz#gmail.com', 'ApS', 'organized'];
Values[1] = ['2022-05-05', 'abc', 'abc#gmail.com', 'cricket overview', 'sheduled']
let result = [];
Values.forEach((val) => {
const obj = data.reduce((accumulator, element, index) => {
return {...accumulator, [element]: val[index]};
}, {});
result.push(obj);
});
console.log(result);
I have two arrays.
let arr1 = ['dog', 'cat', 'mouse']
let arr2 = ['dog']
How to create another third array from the result?
let arr3 = [{dog: true}, {cat: false}, {mouse: false}]
I can't find a way how to create keys from these string?
Map the first array, and use computed property names to generate the keys from the current array item. Generate the value by checking if the 2nd array includes the current key.
const arr1 = ['dog', 'cat', 'mouse']
const arr2 = ['dog']
const result = arr1.map(key => ({
[key]: arr2.includes(key)
}))
console.log(result)
If given an array of ids [1,2,3,4,5]
And an object array:
[{animal:tiger, id:1}, {animal:"fish", id:2}]
What would be the suggested way to return 'tiger, fish'. Would that be through using .map or would a for loop be better for constructing the sentence?
What you need is just go through the list of ids and find corresponding animal in the animals list.
Note, that in case animals list is not expected to store all the animals and some of them are missing, you will need to add additional filter step to be sure that no undefined values appear on the last map step.
const ids = [1,5,2,4,3,6]; // added 6 which is missing in animals
const animals = [
{name:'Tiger',id:1},
{name:'Horse',id:2},
{name:'Mouse',id:3},
{name:'Elephant',id:4},
{name:'Cat',id:5}
];
const result = ids
.map(id => animals.find(a => a.id === id))
.filter(Boolean) // this will exclude undefined
.map(a => a.name)
.join(',');
console.log(result);
var ids = [1,2,3,4,5];
var objects = [{ animal:"tiger", id: 1 }, { animal: "fish", id: 2 }];
objects.map(function(o) { if(ids.includes(o.id)) return o.animal }).join();
I'm guessing you only want the animal names who's id appears in your array. If so, you could filter the array of objects first, followed by a map and a join.
let idarr = [1, 2, 3, 4];
let objarr = [{
animal: "tiger",
id: 1
}, {
animal: "fish",
id: 2
}];
console.log(objarr.filter(x => idarr.includes(x.id)).map(x => x.animal).join(', '))
I suggest two options, depending on your data & use cases.
1. map + find if the animal kingdoms are not too many to loop through.
const animals = [
{animal:tiger, id:1},
{animal:"fish", id:2}
]
const ids = [1,2,3,4,5];
const names = ids.map(id =>
animals.find(animal => animal.id === id));
2. convert animals array to object first, for easier frequent access later. One upfront loop, then easier to access by id later.
const animals = [
{animal: "tiger", id:1},
{animal: "fish", id:2}
]
/*
Convert
[{animal:tiger, id:1}, {animal:"fish", id:2}]
to
{
1: { animal: "tiger", id: 1 },
2: { animal: "fish", id: 2 },
}
*/
const animalsObj = animals.reduce((acc, animal) => {
return {
...acc,
[animal.id]: animal,
}
}, {});
const ids = [1,2,3,4,5];
const names = ids.map(id => animalsObj[id].animal)
I have a JSON response as below:
[{
"id": 1,
"food": {
"fruits": ["Banana", "Orange", "Apple", "Mango"],
"veggies": ["greens", "peppers", "carrot", "potatoes"],
}
},
{
"id": 2,
"food": {
"fruits": ["grapes", "berries", "peach", "pears"],
"veggies": ["cabbage", "spinach"],
"dairy": ["nutmilk", "goatmilk"]
}
}
]
Now i want to merge the Arrays each "id" (1,2 in example) into string ( ; delimited) like below:
id_1 = Banana;Orange;Apple;Mango;greens;peppers;carrot;potatoes
// observer "id_2" has additional array - "dairy"
id_2 = grapes;berries;peach;pears;cabbage;spinach;nutmilk;goatmilk
The key's are dynamic so for some records there are 2 arrays and for some records it can be 3 or 4 and may be 1.
I tried using react/Java Script Array.concat(), but i am not sure how to do it dynamically. Please help me. Thank you.
This is doable easily using Object.values().flat().join(';') demonstrated below:
let arr=[{"id":1,"food":{"fruits":["Banana","Orange","Apple","Mango"],"veggies":["greens","peppers","carrot","potatoes"],}},{"id":2,"food":{"fruits":["grapes","berries","peach","pears"],"veggies":["cabbage","spinach"],"dairy":["nutmilk","goatmilk"]}}];
const result = arr.map(({id,food}) => ({id, food: Object.values(food).flat().join(';')}));
console.log(result);
You may easily restructure the output by simply changing it to e.g. ["id_"+id]: Object.values(...)
First flatten using map, flat and join. Then convert the resulting array of objects to a single object using assign.
var db = [{"id": 1,"food": {"fruits": ["Banana", "Orange", "Apple", "Mango"], "veggies": ["greens","peppers","carrot","potatoes"], }},{"id" : 2,"food": {"fruits": ["grapes", "berries", "peach", "pears" ], "veggies": ["cabbage","spinach"], "dairy": ["nutmilk","goatmilk"]}}];
var flat = db.map(
({id, food}) => ({[`id_${id}`]: Object.values(food).flat().join(';')})
);
var result = Object.assign(...flat);
console.log(result);
This is really two problems: looping through an array of objects to combine them into one object, and looping through an object to concat all of its array.
Tackling the second one first, something like this would work:
const concatArraysInObject = obj =>
Object.values(obj).reduce((result, arr) => result.concat(arr), []);
const input = { a: [1,2,3], b: [4,5,6], c: [7,8,9] };
const output = concatArraysInObject(input);
console.log(output);
Object.values() will give you an array of all arrays in an object.
The reduce() function takes a two parameters: a function and initial value.
The function should also take (at least) 2 parameters: the result of the last call (or initial value) and the current value in the array.
It'll call the function once for each element in the array.
Now, with that solved, we can tackle the first problem.
For this, we can also use reduce() as well, and we'll construct our combined object on each call.
const concatArraysInObject = (obj) =>
Object.values(obj).reduce((result, arr) => result.concat(arr), []);
const mergeObjectsInArray = (arr, dataKey) =>
arr.reduce((result, obj) => ({ ...result, [obj.id]: concatArraysInObject(obj[dataKey]) }), {});
const input = [
{ id: 'A', data: { a: [1,2,3], b: [4,5,6] } },
{ id: 'B', data: { c: [7,8,9], d: [10,11,12] } }
];
const output = mergeObjectsInArray(input, 'data');
console.log(output);
An important note of warning: object key order is NOT guaranteed in JavaScript. While 99% of the time they will be in the order you expect, this is not a guarantee, so if you depend on the order of the keys for the order of the array (if order matters), you'll want to change your input structure. If order doesn't matter, it is probably fine how it is.
Try this using basic for loop. Inside you will compute key dynamically and value being flattened array of Object.values of the iterating object.
var input = [{
id: 1,
food: {
fruits: ["Banana", "Orange", "Apple", "Mango"],
veggies: ["greens", "peppers", "carrot", "potatoes"]
}
},
{
id: 2,
food: {
fruits: ["grapes", "berries", "peach", "pears"],
veggies: ["cabbage", "spinach"],
dairy: ["nutmilk", "goatmilk"]
}
}
];
var temp = [];
for (var i = 0; i < input.length; i++) {
temp.push({
[`id_${input[i].id}`]: Object.values(input[i].food)
.flat(1)
.join(";")
});
}
console.log(temp); // this gives you an array
console.log(Object.assign(...temp));// in case you require one single object
I have an array that i trying to export to excel with SheetJs and I've a problem to convert my data structure the needed data structure.
here are the all the details:
SheetJs wanted header
['key1', 'key2', 'key3', 'key4', 'key5', 'key6']
My array:(with the wanted position inside the new array)
[
1 {key1: 'text1'},
1 {key2: 'text2'},
2 {key2: 'text6'},
1 {key3: 'text3'},
1 {key4: 'text4'},
2 {key4: 'text5'},
3 {key4: 'text5'},
1 {key5: 'text6'},
1 {key6: 'text7'}
]
Wanted result:
[
{'key1': 'text1', 'key2': 'text2', 'key3': 'text3', 'key4': 'text4', 'key5': 'text6', 'key6': 'text7' },
{'key2', 'text1', 'key2': 'text2', 'key4': 'text5'},
{'key4': 'text5'},
]
As you can see I want to restructure the elements according the the number of the appearance of the elements.
I can't even describe what I've tried In the last few hours, stuff like converting the results to an array and hashmap and so, but I just can't get the wanted results.
Any help would be appreciated.
If I understand the desired result correctly:
You would like to create an array of result objects based an array of input objects
The input objects have 1 or more key/value pairs
The result objects are the merged result of the input objects, putting recurring keys to their own object
To achieve this, you can break down the logic as:
Iterate over the input array objects and their key/value pairs
Append values to the first result object without the given key
If there is no result object without a given key, add a new result object with the key/value
What this looks like:
const inputArray = [
{key1: 'text1'},
{key2: 'text2'},
{key2: 'text6'},
{key3: 'text3'},
{key4: 'text4'},
{key4: 'text5'},
{key4: 'text5'},
{key5: 'text6'},
{key6: 'text7'}
]
const resultArray = [];
// Loop over the input key/value objects
inputArray.forEach((inputItem) => {
// Loop over each key/value pair of the input objects (appears to usually be one)
Object.entries(inputItem).forEach(([key, value]) => {
// Search the result array for an existing object without the given key
let outputIndex = -1;
for (let i=0; i<resultArray.length; i++) {
if (!(key in resultArray[i])) {
outputIndex = i;
break;
}
};
// If there is a target output object, set the value for the key
if (outputIndex !== -1) {
resultArray[outputIndex][key] = value;
} else {
// No target result object, create a new one with the key/value
resultArray.push({ [key]: value });
}
});
});
console.log(resultArray);