Looping over a bidimensional array and extract data to a new one - javascript

I have a bidimensional array like this:
const bArray =
[ [ 'Hello World',
'Hi everybody',
'How are you?'
],
[ { text: 'Hola Mundo',
from: [Object],
raw: '' },
{ text: 'Hola a todos',
from: [Object],
raw: '' },
{ text: 'Cómo estás?',
from: [Object],
raw: '' },
]
]
And I need to get as a result, only one array that should look like this:
[
{ en: 'Hello World',
es: 'Hola Mundo' },
{ en: 'Hi everybody',
es: 'Hola a todos' },
{ en: 'How are you?',
es: 'Cómo estás?' },
]
This is how I do it:
let val1 = bArray[0].map(tuple => tuple);
let val2 = bArray[1].map(tuple => tuple);
let result = val1.reduce((arr, v, i) => arr.concat({"en" : v, "es" : val2[i].text}), []);
And now in the result variable, I have only one array with the result showed before.
My question?
Is there any improved way in which I can get the same result but with fewer lines of code? I mean, something like a combination of map with reduce, filter or concat without creating two separte arrays like val1 and val2.

If you simply do:
bArray[0].reduce((arr, v, i) => arr.concat({"en" : v, "es" : bArray[1][i].text}), []);
You can get the same thing in just one line.
Explanation:
let val1 = bArray[0].map(tuple => tuple);
let val2 = bArray[1].map(tuple => tuple);
This is doing nothing but get the elements in the array. It's exactly the same thing as:
let val1 = bArray[0];
let val2 = bArray[1];
So I just direct accessed the bArray indexes in your original line.

I am assuming there will be only two arrays inside outer array. You simply need to loop on first array and pick the text from from other array at same index and merge them into one object.
const bArray =
[ [ 'Hello World',
'Hi everybody',
'How are you?'
],
[ { text: 'Hola Mundo',
from: [],
raw: '' },
{ text: 'Hola a todos',
from: [],
raw: '' },
{ text: 'Cómo estás?',
from: [],
raw: '' },
]
];
let result = bArray[0].map((item, index) => {
return {
en: item,
es: bArray[1][index].text
};
});
console.log(result);

Yet another variation using Array.prototype.forEach() method
let result = [];
bArray[0].forEach((item, index) => {
result.push({
en: item,
es: bArray[1][index].text
});
});
console.log(result);

Related

How to compare two array of objects by mutiple properties using javascript

I have two array of objects in which if property grp from arrobj1 is
same as SERVICE and ISACTIVE is true from arrobj2, then return array of object using
javascript
Tried
let result = arrobj1.filter(e=>
arrobj2.some(i=> i.ISACTIVE===true && e.grp === i.SERVICE);
);
var arrobj1=[
{
id:"SetupFS",
grp:"fs",
title: "xxx"
},
{
id:"ExtendFS",
grp:"fs",
title: "yyy"
},
{
id:"RebootServer",
grp:"os",
title: "yyy"
},
]
var arrobj2=[
{id:1, ISACTIVE:true, TASK:'SetupFS', SERVICE: "fs" },
{id:2, ISACTIVE:false, TASK:'RebootServer', SERVICE:"os" },
{id:3, ISACTIVE:false, TASK:'ExtendFS', SERVICE: "fs" },
]
Expected Result
[
{
id:"SetupFS",
grp:"fs",
title: "xxx"
}
]
You don't need filter for second item, you need to check if the item with corresponding index in arrobj1 with grp value equal to SERVICE value in arrobj2
var arrobj1=[
{
id:"SetupFS",
grp:"fs",
title: "xxx"
},
{
id:"ExtendFS",
grp:"fs",
title: "yyy"
},
{
id:"RebootServer",
grp:"os",
title: "yyy"
},
]
var arrobj2=[
{id:1, ISACTIVE:true, TASK:'SetupFS', SERVICE: "fs" },
{id:2, ISACTIVE:false, TASK:'RebootServer', SERVICE:"os" },
{id:3, ISACTIVE:false, TASK:'ExtendFS', SERVICE: "fs" },
]
let result = arrobj2.filter((item, i) =>
item.SERVICE === arrobj1[i].grp
);
console.log(result)
A simpler method
// gets two results wit the equals
let filteredList = [];
for (const item of arrobj1) {
// include TASK === item.id to get the expected answer
const inArray = arrobj2.find(e => e.ISACTIVE && e.TASK === item.id && e.SERVICE === item.grp);
if (inArray) {
filteredList.push(item)
}
}
console.log(filteredList)
with filters in the question it returns two items
e => e.ISACTIVE && e.SERVICE === item.grp
0: Object
id: "SetupFS"
grp: "fs"
title: "xxx"
1: Object
id: "ExtendFS"
grp: "fs"
title: "yyy"
Hope it helps
but if this is not what was expected, I'll delete the answer

Applying both replace and filter to an object

I need to filter an object by only taking in results that have ".com" in the string whilst also removing a string from it. I can remove the string and the results go into my DB perfectly however I am struggling with the filter. Is there a way I can call both the replace and filter functions inside the same variable being companyFilter?
Assume the object is:
[{
company: 'amazon'
companyurl:'amazon.com'
}
{
company: '400 prize money'
companyurl:'400 prize money'
}
{
company: 'facebook'
companyurl:'facebook.com'
}
{
company: 'google'
companyurl:'google.com'
}
]
const newObject = data.map((item) => {
const companyNoCom = item['companyurl'].replace(/hackerone.com\//g, "")
//const companyFilter = data.filter((item) => item['company'].includes('.com'))
newItem = {...item,
company: companyNoCom,
}
return newItem
})
console.log(newObject)
The required output would be:
[{
company: 'amazon'
companyurl:'amazon.com'
}
{
company: 'facebook'
companyurl:'facebook.com'
}
company: 'google'
companyurl:'google.com'
}
]
Array.map() ALWAYS returns ALL results but allows changes to each object within the array.
Array.filter() on the other hand ONLY filters and cannot change individual objects within the array and should only return a boolean.
If you need to first make changes to the data in order to determine if it should be included, run .map first, then .filter on the results of map(). The original data will be unchanged and newObject will contain your results:
var newObject = data
.map((item) => {
item['companyurl'] = item['companyurl'].replace(/hackerone.com\//g, "");
return item;
})
.filter((item) => item['companyurl'].includes('.com'));
// Note. the original data array will not be changed.
const data = [
{ company: "amazon", companyurl: "amazon.com" },
{ company: "400 prize money", companyurl: "400 prize money" },
{ company: "facebook", companyurl: "facebook.com" },
{ company: "google", companyurl: "google.com" },
];
const newObject = data.filter((item) => item.companyurl.includes(".com"));
console.log(newObject);
const data = [{
company: 'amazon',
companyurl:'amazon.com'
},
{
company: '400 prize money',
companyurl:'400 prize money'
},
{
company: 'facebook',
companyurl:'facebook.com'
},
{
company: 'google',
companyurl:'google.com'
}
]
const result = data.filter(item => item.companyurl.includes(".com")).map(item => ({...item, company: item.companyurl.split(".com")[0]}))
console.log(result)
EDIT: I made an adjustment to match desired output, so with this one you would always get company value coming from companyurl after striping .com part
you can use String.prototype.endsWith() to check if the end of the string is .com and filter by this:
const arr = [{
company: 'amazon',
companyurl:'amazon.com'
},
{
company: '400 prize money',
companyurl:'400 prize money'
},
{
company: 'facebook',
companyurl:'facebook.com'
},
{
company: 'google',
companyurl:'google.com'
}
];
const res = arr.filter(({ companyurl }) => companyurl.endsWith('.com'));
console.log(res);

Not return anything from filter method?

I have a list array:
list: [
{
id: '3',
title: 'hi',
},
{
id: '4',
title: 'there',
},
],
I'm using a method to do some destructuring and return and new array while looking for an item by id
return {
title: section.title,
list: [
...section.list,
storeSections[i].list.filter((field) => field.id === ownId)[0],
],
};
If it finds it, it will just add it to the new array, for example this object:
{
id: '3515',
title: 'hello',
},
But if it doesn't, it will add 'undefined' to the new array, because the filter method will return undefined.
Is there a simple way to change this behavior so that the filter method only adds an item to the array if it finds it?
use spread, when the array is empty you will not get the extra entry.
var a = [1,2,3];
var b = [4];
var c = [];
console.log([...a, ...b, ...c])
so
return {
title: section.title,
list: [
...section.list,
...storeSections[i].list.filter((field) => field.id === ownId),
],
};
One solution I found is to add:
list: [
...section.list,
storeSections[i].list.filter((field) => field.id === ownId)[0],
].filter((item) => item !== undefined),
Anothef filter method to remove the undefined values

Merging by id correctly but get empty object - Javascript

I have two arrays that needs to be merged by id (sourceID), which seems to be done, but both imagesTest objects return empty. Now sure what I am doing wrong here?
My code looks like this:
const eventsToBeInserted1 = [{
name: 'Katy Perry',
slug: 'katy-perry',
sourceID: [1],
tags: ['music', 'jazz'],
images1: ['picture_perry_1', 'picture_perry_2']
},
{
name: 'Lukas Graham',
slug: 'lukas-graham',
sourceID: [2],
tags: ['rock', 'techno'],
images1: ['picture_graham_1', 'picture_graham_2']
}
]
const imagesTest = [{
sourceID: 1,
images: ['picture_perry.jpg']
},
{
sourceID: 2,
images: ['picture_graham.jpg']
}
]
const eventsToBeInserted = eventsToBeInserted1.map(
event => Object.assign({}, event, {
imagesTest: imagesTest
.filter(img => img.sourceID === event.sourceID)
.map(img => img.name)
}))
console.log(eventsToBeInserted)
The problem is that in eventsToBeInserted1 the sourceId is defined as an array: sourceID: [1].
Either change it to be defined as a regular int: sourceID: 1
or change the merge function:
const eventsToBeInserted = eventsToBeInserted1.map(
event => Object.assign({}, event, {
imagesTest: imagesTest
.filter(img => img.sourceID === event.sourceID[0])
.map(img => img.name)
}))

How to convert this mysql select return into one array

Is there anyway to convert this like the example below?
Convert this:
[
RowDataPacket { title: 'Code' },
RowDataPacket { title: 'Pizza' }
]
Into this:
['Code', 'Pizza']
I've provided you two possible solutions, in case if it's just an array of objects or an array of nested objects.
var arr = [{RowDataPacket: { title: 'Code' }}, {RowDataPacket: { title: 'Pizza' }}],
res = arr.map(v => v.RowDataPacket.title);
console.log(res);
var arr = [{ title: 'Code' }, { title: 'Pizza' }],
res = arr.map(v => v.title);
console.log(res);
Create a new array
var newArr = [];
And then push each item into the array
result.forEach(function(obj){
newArr.push(obj.title);
}

Categories