DevelopmentIsMyPassion
DevelopmentIsMyPassion

Reputation: 3591

compare observable arrays with different elements

I wish to compare 2 observable arrays. I have defined 2 observable arrays as below

var data1 = [{name1: "one"}, {name1: "two"}, {name1: "three"}];
var data2 = [{name2: "one"}, {name2: "two"}, {name2: "three"}];

dataOne: ko.observableArray(data1),
dataTwo: ko.observableArray(data2)

You can see data1 has different element name than data2. I wish to compare 2 observable arrays and return data matching with each other. So in our case it will be "two" and "three"

After doing this i will bind this to checkbox which will set checkbox to checkbox with matching data. I have put up fiddle here

I want to bind the checkbox with value from observable array dataTwo. How to achieve this?

Forgot to mention that in my fiddle i have just one checkbox but in my actual scenario it will be multiple checkboxes which will be binded to the data.


I have now updated fiddle. You can see that i am binding checkbox to dataOne but want to be checked based on element in datatwo.

Upvotes: 3

Views: 4701

Answers (1)

Paul Manzotti
Paul Manzotti

Reputation: 5147

I've got to admit, I'm still rather confused as to what you are trying to achieve here. I suggest that you pre-process the two arrays to produce a single array containing the values that are in both arrays. Then, when you are looping over each array, you can see if the current value is in the list of duplicates and check the box if it is.

First, add an observable array to your viewModel:

duplicates: ko.observableArray()

You can flatten each of your arrays using:

var flattenedOne = ko.utils.arrayMap(this.dataOne(), function(item) {
    return item.name1;
});
flattenedOne = flattenedOne.sort();

var flattenedTwo = ko.utils.arrayMap(this.dataTwo(), function(item) {
    return item.name2;
});
flattenedTwo = flattenedTwo.sort();

Then use compare to get the ones that are in both arrays:

var differences = ko.utils.compareArrays(viewModel.flattenedOne, viewModel.flattenedTwo);
//return a flat list of differences
ko.utils.arrayForEach(differences, function(difference) {
    if (difference.status === 'retained') {
        viewModel.duplicates.push(difference.value);
    }
});

Then you data-bind using:

<input type="checkbox" data-bind="checked: duplicates.indexOf(name1) !== -1" />

Working fiddle.

Upvotes: 2

Related Questions