0

This comparison is a bit odd as I have the following format:

Preferences Object:

{ 
  models: [
   {... attributes: {} },
   {... attributes: {} },
   {... attributes: {} }
  ]
}

Data Array:

[{}, {}, {}]

I have this object that contains an array of more objects with a key called attributes.

My Goal:

My goal is to see which items in the Data Array don't exist as the value to the attributes key in the models array using Underscore.JS.

Hacky Attempt:

This is definitely not how I want to code this, but localStorageLayers is the Data Array and the layerPrefs is the Preferences Object is the above labelling.

_.each(localStorageLayers, (localLayer) => {
    var layerWasLoaded = false;
    _.each(layerPrefs.models, (layerPref) => {
        if (_.isEqual(layerPref.attributes, localLayer)) {
            layerWasLoaded = true;
            // Don't do anything
        }
    })
    if (layerWasLoaded == false) {
        // Do stuff
    }
})
2
  • I don't understand. What is your question? Commented Mar 4, 2018 at 16:40
  • @KenrySanchez I've updated the OP. I want to see which items in the data array are never a value to any of the "attributes" keys in the models array of objects. Commented Mar 4, 2018 at 16:42

1 Answer 1

1

You could filter the localStorageLayers down to a subset where the localLayer is found to be equal to none (negated some) of the layerPrefs.models objects as compared to its attributes property.

I don't use lodash, but result should contain only the localStorageLayers that did not find equality in layerPrefs.models.

const layerPrefs = { 
  models: [
   {attributes: {foo: "foo"} },
   {attributes: {foo: "bar"} },
   {attributes: {baz: "baz"} }
  ]
};

const localStorageLayers = [
  {foo: "foo"}, {hot: "dog"}, {hot: "dog"}, {baz: "baz"}
];

const result = _.filter(localStorageLayers, localLayer => 
    !_.some(layerPrefs.models, layerPref =>
        _.isEqual(layerPref.attributes, localLayer)
    )
);

console.log(result);

// Remove duplicates
const noDupes = _.uniqBy(result, _.isEqual);

console.log(noDupes);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>


You could reverse the evaluation of each localLayer by doing _.every with !_.isEqual.

Use which ever seems clearer.

const result = _.filter(localStorageLayers, localLayer => 
    _.every(layerPrefs.models, layerPref =>
        !_.isEqual(layerPref.attributes, localLayer)
    )
);
Sign up to request clarification or add additional context in comments.

6 Comments

Do I need to return the isEqual? This doesn't seem to be working.
The isEqual is returned from the arrow function automatically because I removed the curly braces. As to why it doesn't work, I don't know because you didn't supply complete sample data.
Ah, this is perfect. I was adding curly braces, so needed to return the some and isEqual methods. Thanks so much
I see that I had missed the removal of a brace too, so I fixed it and added a demo. As to duplicate removal, I'd probably just do something similar with the result by filtering down to those that are not equal from the current object forward. I'll add that to my demo.
Looking at their docs, I found _.uniqBy, which filters an array down to a unique set based on the provided predicate. I updated the example to show it working.
|

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.