2

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
        }
   });
4
  • Did you mean to leave out label3?, if so you might want to say you want a union too. Commented Jul 11, 2018 at 11:02
  • yes I want to remove the label3 and just display 2 as the output Commented Jul 11, 2018 at 11:03
  • 1
    Possible duplicate of Getting a union of two arrays in JavaScript Commented Jul 11, 2018 at 11:04
  • Possible duplicate of stackoverflow.com/questions/51282996/… Commented Jul 11, 2018 at 11:06

7 Answers 7

3

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);

Sign up to request clarification or add additional context in comments.

4 Comments

This depends on array2 having all its labels matching in array1.
@CertainPerformance yes. OP can provide a default value in case the value not found. Eg arr.find() || {default object }
I think what @CertainPerformance is meaning is say you changed label2 to say label4 in array2, you will get two results, this violates the union requirement.
thank you for your help, i didnt know such function exists
2

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; }

Comments

1

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);

Comments

1

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);

4 Comments

In Chrome for me run snippet gets -> "Uncaught SyntaxError: Unexpected token {",
Is this answer supposed to compile?
@Keith - It does now. A typo changed removed the , from array2.
@ArmanCharan - It does now. A typo changed removed the , from array2.
0

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)

Comments

0

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)

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.