Javascript how to join two arrays having same property value? - javascript

How do I join arrays with the same property value? I cannot map it because it has different indexes.
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
expected output:
var array3 = [
{'label':"label1",'value':"TEXT",'position':0},
{'label':"label2",'value':"SELECT", 'position':1}
];
This is what I did, I cannot make it work,
var arr3 = arr1.map(function(v, i) {
return {
"label": v.label,
"position": v.position,
"value": arr2[?].value
}
});

I think you can use array#reduce to do something like this perhaps:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3 = array2.reduce((arr, e) => {
arr.push(Object.assign({}, e, array1.find(a => a.label == e.label)))
return arr;
}, [])
console.log(array3);

You could take a Map and check the existence for a new object.
var array1 = [{ label: "label1", position: 0 }, { label: "label3", position: 2 }, { label: "label2", position: 1 }],
array2 = [{ label: "label1", value: "TEXT" }, { label: "label2", value: "SELECT" }],
map = array1.reduce((m, o) => m.set(o.label, o), new Map),
array3 = array2.reduce((r, o) => {
if (map.has(o.label)) {
r.push(Object.assign({}, o, map.get(o.label)));
}
return r;
}, []);
console.log(array3);
.as-console-wrapper { max-height: 100% !important; top: 0; }

As per the effort, we take an assumption that array1 will be having all the labels that are in array2.
Based on that first, create a map for array2and with key being labels. Post that, filter out array1 items which have labels existing in the map and then finally merging the objects of the filtered array and its corresponding values in map extracted from array2.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.filter(({label}) => map[label]).map(o => ({...o, ...map[o.label]}));
console.log(result);
Also, in the above snippet, you can improve the performance further by using Array.reduce against filter and map functions to retrieve the result.
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
let map = array2.reduce((a,{label, ...rest}) => Object.assign(a,{[label]:rest}),{});
let result = array1.reduce((a,o) => {
if(map[o.label]) a.push({...o, ...map[o.label]});
return a;
}, []);
console.log(result);

If you don't know in advance which array(s) will have their labels be a subset of the other (if any), here's a method that allows for either array1 or array2 to have labels that the other array lacks. Use reduce over array1, finding the matching label in array2 if it exists:
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
const output = array1.reduce((a, { label, position }) => {
const foundValueObj = array2.find(({ label: findLabel }) => findLabel === label);
if (!foundValueObj) return a;
const { value } = foundValueObj;
a.push({ label, value, position });
return a;
}, []);
console.log(output);

See Array.prototype.map() and Map for more info.
// Input.
const A = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}]
const B = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}]
// Merge Union.
const mergeUnion = (A, B) => {
const mapA = new Map(A.map(x => [x.label, x]))
return B.map(y => ({...mapA.get(y.label), ...y}))
}
// Output + Proof.
const output = mergeUnion(A, B)
console.log(output)

This works.
Approach: Concatenate the objects with same label, using Object.assign()
var array1 = [{'label':"label1",'position':0},{'label':"label3",'position':2},{'label':"label2",'position':1}];
var array2 = [{'label':"label1",'value':"TEXT"},{'label':"label2",'value':"SELECT"}];
var result = [];
array2.forEach(function(value, index){
result.push(Object.assign({},array1.find(function(v,i){return v.label==value.label}),value));
});
console.log(result)

Im not good with javascript,but you could also do this
var array1 = [
{'label':"label1",'position':0},
{'label':"label3",'position':2},
{'label':"label2",'position':1},
];
var array2 = [
{'label':"label1",'value':"TEXT"},
{'label':"label2",'value':"SELECT"}
];
var array3=[];
for(var i=0;i<array1.length;i++)
{
for(var x=0;x<array2.length;x++)
{
console.log(array1[i]['label'] == array2[x]['label']);
if(array1[i]['label'] == array2[x]['label']){
array3.push({label:array1[i]['label'],value:array2[x]['value'],position:array1[i]['position']});
}
}
}
console.log(array3);

Related

Increase count property on object if duplicate value exists in an array

I would like to take list variable and get it to the point that updated list is at but am unsure how.
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = [{name:'apple', count:2},{name:'banana', count: 1}];
Maybe this example will help you ?
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = Object.values(list.reduce(
(map, el) => {
map[el.name] ? map[el.name].count++ : map[el.name] = { ...el,
count: 1
};
return map;
}, {}
));
console.log(updatedList);
function uptadeLi(list,item,quant) {
// body...
for( i in list){
if (list[i].name === item){
list[i].count = quant
}
}
}
With that function you can set each one of the elements of lists , be sure to put the name of item as string
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const res = list.reduce((sub,value)=>{
const index= sub.findIndex(i => i.name===value.name)
if(index !==-1)
sub[index].count++
else
sub.push({name:value.name,count:1})
return sub
},[])
console.log(res)
Use .reduce() method to evaluate the count for each item into an object with unique keys:
{ "apple": 2, "banana": 1 }
Then use Object.entries() to convert this into the following array:
[ ["apple", 2], ["banana", 1] ]
Finally, use .map() method to produce:
[ {"name": "apple", "count": 2}, {"name": "banana", "count": 1} ]
DEMO
const list = [{name:'apple'},{name:'apple'},{name:'banana'}];
const updatedList = Object.entries(
list.reduce(
(acc,cur) => ({...acc,[cur.name]:(acc[cur.name] || 0) + 1}),
{})
)
.map(([name,count]) => ({name,count}));
console.log( updatedList );

Transform 2D array to object and use first array element as key

Imagine I have this array of arrays:
myData = [
["wantThisAsKey1",someElement1,anotherElement1],
["wantThisAsKey2",someElement2,anotherElement2]
]
I need to convert this array to an object where the first element of each array is used as the key:
myDataObject = {
"wantThisAsKey1": [someElement1,anotherElement1],
"wantThisAsKey2": [someElement2,anotherElement2],
}
How can I do this in a general way, something like myDataObject = convertToObject(myData) ?
Try this:
let myData = [
["wantThisAsKey1","someElement1","anotherElement1"],
["wantThisAsKey2","someElement2","anotherElement2"]
];
let myDataObject = convertToObject(myData);
console.log(myDataObject);
function convertToObject(data){
let res = {};
for(let i = 0; i < data.length; i++)
res[data[i][0]] = data[i].slice(1);
return res;
}
To achieve this you can combine the arrays reduce function with destructuring assignment:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
myData = [
["wantThisAsKey1", 1, 2],
["wantThisAsKey2", 2, 3]
]
const newobject = myData.reduce((acc, elem) => {
const [key, ...rest] = elem;
acc[key] = rest
return acc;
}, {})
console.log(newobject);
// Result: { wantThisAsKey1: [ 1, 2 ], wantThisAsKey2: [ 2, 3 ] }
try using reduce here. like this.
const result = myData.reduce( (result, ele) => {
const [key, ...other] = ele
result[key] = other
return result
}, {})
// output = { wantThisAsKey1: [ 'someElement1', 'anotherElement1' ], wantThisAsKey2: [ 'someElement2', 'anotherElement2' ] }

How to create new array with key and value with 2 arrays?

I have 2 array, one for key and other for value.
Want create new array with these arrays.
key: [01, 02, 03]
value: ["hi", "hello", "welcome"]
Output I need:
[
{"key": "1","value":"hi"},
{"key": "2","value":"hello"},
{"key": "3","value":"welcome"}
]
How to get result by this way.?
My code:
output = key.map(function(obj, index){
var myObj = {};
myObj[value[index]] = obj;
return myObj;
})
Result:
[
{"1","hi"},
{"2","hello"},
{"3","welcome"}
]
const keys = [01, 02, 03];
const values = ['hi', 'hello', 'welcome'];
const res = keys.map((key, ind) => ({ 'key': ''+key, 'value': values[ind]}));
console.log(res);
There is also a proposal for the following method of Object, fromEntries, which will do exactly what you want to, but it is not supported yet by the major browsers:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
var myArray = [];
var keys = [45, 4, 9];
var cars = ["Saab", "Volvo", "BMW"];
cars.forEach(myFunction);
var txt=JSON.stringify(myArray);
document.getElementById("demo").innerHTML = txt;
function myFunction(value,index,array) {
var obj={ key : keys[index], value : value };
myArray.push(obj);
}
<p id="demo"></p>
You could take an object with arbitrary count of properties amd map new objects.
var key = [1, 2, 3],
value = ["hi", "hello", "welcome"],
result = Object
.entries({ key, value })
.reduce((r, [k, values]) => values.map((v, i) => Object.assign(
{},
r[i],
{ [k]: v }
)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here you have another apporach using reduce():
let keys = [01, 02, 03];
let values = ['hi', 'hello', 'welcome'];
let newArray = keys.reduce((res, curr, idx) => {
res.push({'key': curr.toString(), 'value': values[idx]});
return res;
}, []);
console.log(newArray);

Combine several arrays into an array of objects in JavaScript

Say I have three arrays depicting some names, number of books read and how awesome these people [in names] are:
let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];
I'm trying to use .reduce() to bring them together to create an array of objects containing the relevant index in each array, but I am failing miserably:
let people = [
{
name: "Mary",
noOfBooks: 2,
awesomeness: "pretty cool"
},
{
name: "Joe",
noOfBooks: 1,
awesomeness: "meh"
},
{
name: "Kenan",
noOfBooks: 4,
awesomeness: "super-reader"
}
]
I got it with reduce as well:
let arrFinal = [];
names.reduce(function(all, item, index) {
arrFinal.push({
name: item,
noOfBooks: numberOfBooks[index],
awesomeness: awesomenessLevel[index]
})
}, []);
You could do it with map, like this:
let result = names.map( (v, i) => ({
name: names[i],
noOfBooks: numberOfBooks[i],
awesomenessLevel: awesomenessLevel[i]
}));
let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];
let result = names.map( (v, i) => ({
name: names[i],
noOfBooks: numberOfBooks[i],
awesomenessLevel: awesomenessLevel[i]
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
map works better than reduce in this case, because the number of elements you have in the names array (or any of the two others) is the same as the number of elements you need in the output. In that case it is more natural to use map.
Use map to create a 1-to-1 mapping between the input arrays and the output arrays.
let people = names.map(function (e, i) {
return {name:e, noOfBooks:numberOfBooks[i],awesomeness: awesomenessLevel[i]};
});
let names = ["Mary", "Joe", "Kenan"];
let numberOfBooks = [2, 1, 4];
let awesomenessLevel = ["pretty cool", "meh", "super-reader"];
let people = names.map(function (e, i) {
return {name:e, noOfBooks:numberOfBooks[i],awesomeness: awesomenessLevel[i]};
});
console.log(people);
You could use a dynamic approach by combining all arrays to one object and use the key names as property names for the result objects in the array
let names = ["Mary", "Joe", "Kenan"],
numberOfBooks = [2, 1, 4],
awesomenessLevel = ["pretty cool", "meh", "super-reader"],
object = { name: names, noOfBooks: numberOfBooks, awesomeness: awesomenessLevel },
result = Object.keys(object).reduce((r, k) =>
(object[k].forEach((a, i) =>
(r[i] = r[i] || {})[k] = a), r), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

array map, map array as a key of an array

I know the title might sounds confusing, but i'm stuck for an hour using $.each. Basically I have 2 arrays
[{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
and [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
How do I put one into another as a new property key like
[{
"section_name": "abc",
"id": 1,
"new_property_name": [{
"toy": "car"
}, {
"tool": "knife"
}]
}, {
"section_name": "xyz",
"id": 2,
"new_property_name": [{
"weapon": "cutter"
}]
}]
ES6 Solution :
const arr = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
const arr2 = [{"toy":"car","id":1},{"tool":"knife","id":1},{"weapons":"cutter","id":2}];
const res = arr.map((section,index) => {
section.new_property_name = arr2.filter(item => item.id === section.id);
return section;
});
EDIT : Like georg mentionned in the comments, the solution above is actually mutating arr, it modifies the original arr (if you log the arr after mapping it, you will see it has changed, mutated the arr and have the new_property_name). It makes the .map() useless, a simple forEach() is indeed more appropriate and save one line.
arr.forEach(section => {
section.new_property_name = arr2.filter(item => item.id === section.id));
});
try this
var data1 = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
var data2 = [{"toy":"car","id":1},{"tool":"knife","id":1},{"weapons":"cutter","id":2}];
var map = {};
//first iterate data1 the create a map of all the objects by its ids
data1.forEach( function( obj ){ map[ obj.id ] = obj });
//Iterate data2 and populate the new_property_name of all the ids
data2.forEach( function(obj){
var id = obj.id;
map[ id ].new_property_name = map[ id ].new_property_name || [];
delete obj.id;
map[ id ].new_property_name.push( obj );
});
//just get only the values from the map
var output = Object.keys(map).map(function(key){ return map[ key ] });
console.log(output);
You could use ah hash table for look up and build a new object for inserting into the new_property_name array.
var array1 = [{ "section_name": "abc", "id": 1 }, { "section_name": "xyz", "id": 2 }],
array2 = [{ "toy": "car", "section_id": 1 }, { "tool": "knife", "section_id": 1 }, { "weapons": "cutter", "section_id": 2 }],
hash = Object.create(null);
array1.forEach(function (a) {
a.new_property_name = [];
hash[a.id] = a;
});
array2.forEach(function (a) {
hash[a.section_id].new_property_name.push(Object.keys(a).reduce(function (r, k) {
if (k !== 'section_id') {
r[k] = a[k];
}
return r;
}, {}));
});
console.log(array1);
Seems like by using Jquery $.merge() Function you can achieve what you need. Then we have concat function too which can be used to merge one array with another.
Use Object.assign()
In your case you can do it like Object.assign(array1[0], array2[0]).
It's very good for combining objects, so in your case you just need to combine your objects within the array.
Example of code:
var objA = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}];
var objB = [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
var objC = Object.assign({},objA[0],objB[0]);
console.log(JSON.stringify(objC));// {"section_name":"abc","id":1,"toy":"car","section_id":1}
For more info, you can refer here: Object.assign()
var firstArray = [{"section_name":"abc","id":1},{"section_name":"xyz","id":2}],
secondArray = [{"toy":"car","section_id":1},{"tool":"knife","section_id":1},{"weapons":"cutter","section_id":2}];
var hash = Object.create(null);
firstArray.forEach(s => {
hash[s.id] = s;
s['new_property_name'] = [];
});
secondArray.forEach(i => hash[i['section_id']]['new_property_name'].push(i));
console.log(firstArray);

Categories