Brandon Durham
Brandon Durham

Reputation: 7707

Comparing values from several JS arrays

The facts:

What I need:

Example:

Here is a small example of a collection of arrays I’ll be working with:

p1 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
p2 = ["size__18px", "tracking__0", "font__Operator--1408", "alignment__left"];
p3 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
p4 = ["alignment__left", "size__18px"];

This collection of arrays should return something like:

return {
    alignment: 'left',
    font: false,
    leading: false,
    size: '18px',
    tracking: false
}

Suggestions? Every angle I approach this from just seems slow and inefficient. I’m using lodash in this project, in case that simplifies things at all.

Upvotes: 0

Views: 80

Answers (4)

Mike Kozak
Mike Kozak

Reputation: 26

Here's something I threw together.

'use strict';
const originalArrays = [
  ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"],
  ["size__18px", "tracking__0", "font__Operator--1408", "alignment__left"],
  ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"],
  ["alignment__left", "size__18px"]
]
const countInArray = (array, what) => {
  lt count = 0;
  for(let i = 0; i < array.length; i++) {
    if(array[i] === what) {
      count++;
    }
  }
  return count;
};
const theFunction = (originalArrays) => {
  const flattenedArray = originalArrays.reduce((a, b) => a.concat(b));
  let interimResults = [];
  let results = {};

  for(let item of flattenedArray) {
    if(countInArray(flattenedArray, item) === originalArrays.length) {
      if(interimResults.indexOf(item) === -1) {
        interimResults.push(item)
      }
    } else {
      results[item.split('__')[0]] = false;
    }
  }

  for(let result of interimResults) {
    let parts = result.split('__');
    results[parts[0]] = parts[1];
  }
  return results;
};

Upvotes: 1

DonovanM
DonovanM

Reputation: 1198

Here's what I came up with. Didn't come out as clean as I intended but it seems to get the job done.

p1 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
p2 = ["size__18px", "tracking__0", "font__Operator--1408", "alignment__left"];
p3 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
p4 = ["alignment__left", "size__18px"];

var classes = [p1, p2, p3, p4],
    flat = classes.reduce(function(prev, curr) { return prev.concat(curr) }, []),
    unique = flat.reduce(function(prev, curr) { 
      return prev.indexOf(curr) == -1 ? prev.concat([curr]) : prev;
    }, []);

var result = {};

unique.forEach(function (style) {
  result[style.split('__')[0]] = classes.every(function (clss) {
    return clss.indexOf(style) !== -1;
  }) ? style.split('__')[1] : false;
})

document.getElementById('result').innerHTML = JSON.stringify(result, null, 4);
<body>
  <pre id="result">
  </pre>
</body>

Upvotes: 0

umesh kadam
umesh kadam

Reputation: 71

I haven't tested this. If I understand your problem correctly the following could be one of the ways to solve this. I cannot say if this is optimal. I'll try to figure out a better way. But for now here's the code.

var functionWhichHasAccessToArrays() {
    var totalNoOfArrays = someNumber; // 2 or dozens

    function doAllArraysHaveSameValue(value) {
        return !!(_.every(arrayOfArrays, function(array) {
            return (-1 !== _.indexOf(array, value));
        }));
    }

    var result = {};
    _.each(arrayWithMaxLength, function(valueInArray){
        var keyValue = valueInArray.split('__');
        if (doAllArraysHaveSameValue(valueInArray)) {
           result[keyValue[0]] = keyValue[1];
        } else {
            result[keyValue[0]] = false;
        }
    })
}

Upvotes: 0

JesusTinoco
JesusTinoco

Reputation: 11828

Find below a simple way to achieve that using lodash:

const u = require('lodash');

var p1 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
var p2 = ["size__18px", "tracking__0", "font__Operator--1408", "alignment__left"];
var p3 = ["alignment__left", "size__18px", "leading__170", "tracking__0", "font__Operator--1408"];
var p4 = ["alignment__left", "size__18px"];

// I will obtain the unique values from the arrays given using the `union` method:
var union = u.union(p1, p2, p3, p4)

// Then, I will create an array of unique values that are included in all given arrays.
var inter = u.intersection(p1, p2, p3, p4)

// Finally, you can use the `difference` method to obtain those unique values 
// that are not included in the `union` array.
var diff = u.difference(union, inter);

So, in the inter array you will have the classNames that have the same value in all of the array defined above (p1, p2, p3, p4) and the diff array will have all of the namespaces that were not included in each array.

Upvotes: 1

Related Questions