Related
I have two arrays, my aim is to filter the second array arr2 by the first array arr1, and get only matched values where prid is the same as arr2 id, results should be let filtred = [ {name:'kiwi', color:'red', id:12123},{name:'kiwi', color:'red', id:12123}], how i can ichieve this using filter?
let arr1 = [
{prid:12123},
{prid:12124}
]
let arr2 = [
{name:'kiwi', color:'red', id:12123},
{name:'kiwi2', color:'blue',id:12129},
{name:'kiwi3', color:'green',id:12124}
]
Please note: According to your requirement your expected output is not correct:
You can try using Array.prototype.some() inside Array.prototype.filter() by matching the respective property value (prid of arr1 with id of arr2).
let arr1 = [
{prid:12123},
{prid:12124}
]
let arr2 = [
{name:'kiwi', color:'red', id:12123},
{name:'kiwi2', color:'blue',id:12129},
{name:'kiwi3', color:'green',id:12124}
]
let filtred = arr2.filter(i => arr1.some(j => j.prid == i.id))
console.log(filtred);
You can use Array.prototype.reduce which allows to create another array with different structure
let arr1 = [
{prid:12123},
{prid:12124}
]
let arr2 = [
{name:'kiwi', color:'red', id:12123},
{name:'kiwi2', color:'blue',id:12129},
{name:'kiwi3', color:'green',id:12124}
]
let results = arr2.reduce((accumulator, currentItem) =>{
let itemExists = arr1.findIndex(item => item.prid === currentItem.id);
return itemExists !== -1? accumulator.concat(currentItem): accumulator;
}, []);
console.log(results);
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)
This question already has answers here:
Convert an array to an array of objects
(4 answers)
Closed 2 years ago.
I have Array of Array in JavaScript as follows:
myarr = [Array(3), Array(3)]
It has values:
[
['ID', 'Name', 'BloodGroup'],
[1, 'Jim', 'B+'],
[2, 'Jane', 'A+']
]
I want array of object as:
[{'ID':1,'Name':'Jim', 'BloodGroup': 'B+'}, ....]
Is there any way to achieve this using plain js or jQuery without using for loop, as data I get might be big, and server side is not an option.
Destructing is perhaps a way to go?
const arr = [
['ID', 'Name', 'BloodGroup'],
[1, 'Jim', 'B+'],
[2, 'Jane', 'A+']
]
const titles = data[0]; // not used yet
const obj = arr.slice(1).map(([ID, Name, BloodGroup]) => ({ ID, Name, BloodGroup }))
console.log(obj)
I think I might miss one more level of abstraction using the titles but I am still investigating
#NinaScholz got me a more abstract example
const arr = [
['ID', 'Name', 'BloodGroup'],
[1, 'Jim', 'B+'],
[2, 'Jane', 'A+']
]
const titles = arr[0];
const obj = arr.slice(1).map(
arr => Object.fromEntries(
titles.map(
(t, i) => [t, arr[i]]
)
)
);
console.log(obj)
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);
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>