Merge two array javascript - javascript

I have two almost identical arrays of objects, the only difference between them is that the first array consists of inner arrays with objects having a text1 attribute, and the second array has text2 property instead. Each array contains 800 objects with same keys 1, 2, 3, 4 ....
How can I merge these two arrays? I tried with push function but got only the first array. Is there some other way to merge two arrays like reduce, filter or some other function?
let arr1 = [{
"1": [{
"text1": "Some text 1",
"englishName": "Name 1",
"number": 1,
},
{
"text1": "Some text 2",
"englishName": "Name 2",
"number": 2,
}
]
},
{
"2": [{
"text1": "Some text 3",
"englishName": "Name 3",
"number": 3,
},
{
"text1": "Some text 4",
"englishName": "Name 4",
"number": 4,
}
]
}
]
let arr2 = [{
"1": [{
"text2": "Some new text",
"englishName": "Name 1",
"number": 1
},
{
"text2": "Some new text 2",
"englishName": "Name 2",
"number": 2,
}
]
},
{
"2": [{
"text2": "Some new text 3",
"englishName": "Name 3",
"number": 3,
},
{
"text2": "Some new text 4",
"englishName": "Name 4",
"number": 4,
}
]
}
]
i need to merge in one array and concat text2 to first array like this
let mergearray = [
{
"1": [
{
"text1": "Some text 1",
"text2": "Some new text 1",
"englishName": "Name 1",
"number": 1,
},
{
"text1": "Some text 2",
"text2": "Some new text 2",
"englishName": "Name 2",
"number": 2,
}
]
},
{
"2": [
{
"text1": "Some text 3",
"text2": "Some new text 3",
"englishName": "Name 3",
"number": 3,
},
{
"text1": "Some text 4",
"text2": "Some new text 4",
"englishName": "Name 4",
"number": 4,
} ] } ]
How compare keys of arrays?

you can use JavaScript Array concat() method
the concat() method is used to join two or more arrays.
This method does not change the existing arrays, it returns a new array, containing the values of the joined arrays. you can do that like this
let arr= arr1.concat(arr2);
console.log(JSON.stringify(arr));
it will give you this result
[{"1":[{"text1":"Some text 1","englishName":"Name 1","number":1},{"text1":"Some text 2","englishName":"Name 2","number":2}]},
{"2":[{"text1":"Some text 3","englishName":"Name 3","number":3},{"text1":"Some text 4","englishName":"Name 4","number":4}]},
{"1":[{"text2":"Some new text","englishName":"Name 1","number":1},{"text2":"Some new text 2","englishName":"Name 2","number":2}]},
{"2":[{"text2":"Some new text 3","englishName":"Name 3","number":3},{"text2":"Some new text 4","englishName":"Name 4","number":4}]}]

Try this:
const arr3 = arr1.reduce((acc, item, index, array) => {
if (arr2.length > index) {
array[index][index + 1][0].text2 = arr2[index][index + 1][0].text2;
acc = array.map((item, index2) => {
return item[index2 + 1][0];
});
}
return acc;
}, []);
console.log(JSON.stringify(arr3.reverse()))

Related

React Native - sort array based off values in common

Hey guys I have the following array that's used to display a flatlist within my app.
Array [
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
},
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "1,16,19",
},
]
However I would like to sort this array based off the subjects value. In the app the user can select a couple of subjects which are represented by numbers so lets say the users selected subjects are:
11, 4, 2, 1
I would like to sort the array so that the items with 3 or more subjects in common with the user are sorted to the top and then items with two and then 1 and then none so the array above should look like this after sorting:
Array [
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
},
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "0,16,19",
},
]
How can I achieve this?
I have been searching around the array sort function:
Array.prototype.sort()
However I have only seen how to sort based off number comparisons I have never seen an array sorted based off values in common. Please could someone help me with this!
EDIT
Array [
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
"ranking": "green",
},
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
"ranking": "amber",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
"ranking": "amber",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "0,16,19",
"ranking": "red",
},
]
You could create an object with counts of selected subjects and sort descending by this value.
const
data = [{ data: "Item 1", id: "1", subjects: "1,8,9,23,11,15,16,14,20" }, { data: "Item 2", id: "2", subjects: "8,11,2,4,16,19" }, { data: "Item 3", id: "3", subjects: "16,20,14,11,9,2" }, { data: "Item 4", id: "4", subjects: "1,16,19" }],
selected = [11, 4, 2, 1],
counts = data.reduce((r, { id, subjects }) => {
r[id] = subjects
.split(',')
.reduce((s, v) => s + selected.includes(+v), 0);
return r;
}, {});
data.sort((a, b) => counts[b.id] - counts[a.id]);
console.log(data);
console.log(counts);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Creating a nested array from a flat array - JavaScript

I'm looking to create a nested array based on reading a flat array. An example of the flat array I am reading is this:
const flatItems = [
{
"code": "CODE1",
"title": "Title 1",
"question": "Question 1",
"order": 0,
},
{
"code": "CODE2",
"title": "Title 2",
"question": "Question 2",
"order": 1,
},
{
"code": "CODE3",
"title": "Title 3",
"question": "Question 3",
"order": 2,
},
{
"code": "CODE4",
"title": "Title 4",
"question": "Question 4",
"order": 3,
},
];
And ideally I would like to place this into groups of 'Yes's and 'No's. The flat array is already in the correct order. There will only ever be one item in the 'Yes's but can have many in the 'No's depending on any conditions.
const treeItems = {
question: "Question 1",
options: [
{
value: "Yes",
items: [
{
code: "CODE1",
title: "Title 1"
}
]
},
{
value: "No",
question: "Question 2"
options: [
{
value: "Yes",
items: [
{
code: "CODE2",
title: "Title 2"
}
]
},
{
value: "No",
items: [
{
code: "CODE3",
title: "Title 3"
},
{
code: "CODE4",
title: "Title 4"
}
]
}
]
}
]
};
I am aware that reduce may be the best approach here, but would anyone have any good examples or recommended practices as how I should go about doing this?
If you want to group these items use "Yes" and "No" as the properties of the final object.
Using Array.reduce() sounds solid in this case.
Not sure how you want to group because your JSON is inconsistent.
const flatItems = [
{
"code": "CODE1",
"title": "Title 1",
"question": "Question 1",
"order": 0,
},
{
"code": "CODE2",
"title": "Title 2",
"question": "Question 2",
"order": 1,
},
{
"code": "CODE3",
"title": "Title 3",
"question": "Question 3",
"order": 2,
},
{
"code": "CODE4",
"title": "Title 4",
"question": "Question 4",
"order": 3,
},
];
const groupedObject = flatItems.reduce((tmpGroupedObject, item) => {
const groupingProperty = item.order < 2 ? "Yes" : "No"; /// grouping decision
if (!Array.isArray(tmpGroupedObject[groupingProperty])) {
tmpGroupedObject[groupingProperty] = []; /// make Obj["Yes"] an array
}
tmpGroupedObject[groupingProperty].push(item);
return tmpGroupedObject;
}, {});
console.log(groupedObject);
As mentioned in the comments, I'm confused by the requested output. I especially don't understand why CODE3 and CODE4 are on the same level, and not nested as another Yes/No pair. But we can write a fairly simple recursion to do that:
const convert = ([{code, title, question} = {}, ...items]) => ({
question,
options: [
{value: "Yes", items: [{code, title}]},
{value: "No", ... (items .length < 3 ? {items: items .map (({code, title}) => ({code, title}))} : convert (items))}
]
})
const flatItems = [{code: "CODE1", title: "Title 1", question: "Question 1", order: 0}, {code: "CODE2", title: "Title 2", question: "Question 2", order: 1}, {code: "CODE3", title: "Title 3", question: "Question 3", order: 2}, {code: "CODE4", title: "Title 4", question: "Question 4", order: 3}]
console .log (
convert (flatItems)
)
.as-console-wrapper {max-height: 100% !important; top: 0}
However by changing < 3 to < 2, we get what I think of as a much more logical grouping:
const convert = ([{code, title, question} = {}, ...items]) => ({
question,
options: [
{value: "Yes", items: [{code, title}]},
{value: "No", ... (items .length < 2 ? {items: items .map (({code, title}) => ({code, title}))} : convert (items))}
]
})
const flatItems = [{code: "CODE1", title: "Title 1", question: "Question 1", order: 0}, {code: "CODE2", title: "Title 2", question: "Question 2", order: 1}, {code: "CODE3", title: "Title 3", question: "Question 3", order: 2}, {code: "CODE4", title: "Title 4", question: "Question 4", order: 3}]
console .log (
convert (flatItems)
)
.as-console-wrapper {max-height: 100% !important; top: 0}
I hope one of these does what you want.
Also, again, welcome to StackOverflow. Next time, please be sure to post your own attempted solution in the question. Even if it's not working properly, we can often either help you fix it, or explain why it's headed down the wrong path altogether.

Find a specific object in an array of objects

I don't understand because I use the method "find" but I get "undefined"...
My data :
[
{ "id": 2, "title": "My project", "nameStructure": "Entreprise", "studies":
[
{"id": 3, "name": "My stidue", "status": "in prepa" },
{ "id": 4, "name": "My second study ", "status": "In"}
],
"typeStructure": "Entreprise"
},
{ "id": 3, "title": "My project 2", "nameStructure": "Entreprise 2", "studies":
[
{"id": 4, "name": "My stidue 2", "status": "in prepa" },
{ "id": 5, "name": "My second study 2 ", "status": "In"}
],
"typeStructure": "Entreprise 2"
},
...
]
I would like to have only the object with the ID 2 for example.
So I wrote :
const id = 2
myarray.filter(p => p.id === id);
But it does not work... I always get "undefined"
Thanks for help
ID is a number, therefore you need to remove the quotes around 2
myarray.filter(p => p.id === 2);
and the operator === in Javascript means that 2 should be equal to "2" as in value and type
reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality
const arr = [
{
id: 2,
title: "My project",
nameStructure: "Entreprise",
studies: [
{ id: 3, name: "My stidue", status: "in prepa" },
{ id: 4, name: "My second study ", status: "In" }
],
typeStructure: "Entreprise"
},
{
id: 3,
title: "My project 2",
nameStructure: "Entreprise 2",
studies: [
{ id: 4, name: "My stidue 2", status: "in prepa" },
{ id: 5, name: "My second study 2 ", status: "In" }
],
typeStructure: "Entreprise 2"
}
];
const newItem = arr.find((item) => item.id === 2);
console.log("newItem>>>>", newItem);

How to reformat object using its property value as property key?

how can I assign object property value as property key?
I have a set of data:
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
]
I want to reformat it to become:
const mydata = [
{
"Title 1": "Value 1"
},
{
"Title 2": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
]
},
]
I have tried this code to achieve it:
mydata.map((dt: any) => {
dt.title: dt.value
});
However, it seems not working.
Any idea how can I reformat it to the one I desire?
Thanks.
Please use following code.
Reference URL How to use a variable for a key in a JavaScript object literal?
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
];
let reData = [];
mydata.forEach((dt)=>{
reData.push({[dt.title]: dt.value});
});
console.log(reData);
If you want to transform the array to a different type of variable, use [reduce][1]
const mydata = [
{
id: 001,
value: "Value 1",
title: "Title 1",
},
{
id: 002,
value: [
{
Name: "Name 1",
Age: "20",
},
{
Name: "Name 2",
Age: "30",
},
],
title: "Title 2",
},
];
const data = mydata.reduce(
(acc, cur) => ({ ...acc, [cur.title]: cur.value }),
{}
);
console.log(data);
Your map function has an error, and your key assignment has another one. Let's fix it.
const newData = mydata.map((dt: any) => ({
[dt.title]: dt.value,
}));
First: You can't return an object from an arrow function without parenthesis, if you don't use it, the code will think it is a function body not an object.
Second: If you want to return a value as a key, you need put it inside "[ ]" (Square brackets)
Just that, simple mistakes, at the end you came up with the right logic to solve it
Add brackets around the return value.
Use square brackets for a computed property name.
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
];
const res = mydata.map(({value, title})=>({[title]: value}));
console.log(res);

lodash filter in array

in lodash there is a possibility to filter within an array which is in an object?
I have an object that has an array in it. It looks like this
{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}
What I want to do now.
If the tag is Red he should output the object with the ids: 1 and 2. Tag = Green only the object with the id: 3. And so on.
I have now tried to solve this with the lodash filter.
const filteredColors = _.filter(colors, function(c) {
return _.includes(['Test 1', 'Test 2'], c.name);
});
// returns Objects with 2 Entrys = Correct
I can filter normal values, but how can I find the value in the array?
I have solved it with:
let filter = _.filter(
colors,
_.flow(
_.property('tag'),
_.partial(_.intersection, ['red', 'green']),
_.size,
),
);
There's no need for lodash, just check if the tag array includes what you're looking for:
const arr = [{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}];
console.log(
arr.filter(({ tag }) => tag.includes('red'))
);
Convert your array to String, and then you can check string is contain your colour or not. Like.
const items = [
{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}]
function findColorId(color){
return items.filter((d)=> {
if(String(d.tag).includes(color)){
return d;
}
});
}
findColorId('red');
You can use Array.prototype.filter():
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
and Array.prototype.map():
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
const colors = [{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}]
function filteredColors(colorsArr, c){
return colorsArr.filter(i => i.tag.includes(c)).map(i => ({id: i.id}));
}
console.log(filteredColors(colors, 'red'));
console.log(filteredColors(colors, 'green'));
This in lodash is somewhat longer than with ES6.
const data = [{ "id": "1", "name": "Test 1", "tag": ["blue","red", "yellow"] }, { "id": "2", "name": "Test 2", "tag": ["red", "yellow"] }, { "id": "3", "name": "Test 3", "tag": ["green"] }]
// lodash
const lodash = c => _.filter(data, x => _.includes(x.tag,c))
// ES6
const es6 = c => data.filter(x => x.tag.includes(c))
console.log(lodash('green'))
console.log(es6('green'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
The idea in both is to simply use _.filter / Array.filter and then _.includes / Array.includes

Categories

Resources