0

I have been trying to combine objects with same value. The object that I have is like this:

{
  'Mon': [{'apple': 'A', 'color': 'green'}, {'apple':'B', 'color':'yellow'}],
  'Tue': [{'apple': 'A', 'color': 'green'}, {'apple':'B', 'color':'yellow'}],
  'Wed': [],
  'Thu': [],
  'Fri': [{'banana': 'A', 'color': 'yellow'}],
  'Sat': [{'banana': 'A', 'color': 'yellow'}],
  'Sun': [{'banana': 'A', 'color': 'yellow'}]
}

I have been trying to find a way to combine these so that the result would be like this:

{
  ['Mon', 'Tue']: [{'apple': 'A', 'color': 'green'}, {'apple':'B','color':'yellow'}],
  ['Wed', 'Thu']: [],
  ['Fri','Sat','Sun']: [{'banana': 'A', 'color': 'yellow'}]
}

Is there some way to do this with lodash ? or pure js ?

1
  • That result is invalid data format. Commented Feb 7, 2017 at 14:58

1 Answer 1

1

In Javascript the keys of an object have to be strings.

However, you can use arrays, they will be casted to string:

var a = {};

a[['Mon', 'Tue']] = 1;

console.log(a[['Mon', 'Tue']])
console.log(a)

But, of course, they keys of the final object would be string. Anyway, should be trivial to create a function to convert them back to array, if you need them.

About processing the data, I'd go like this:

var original = {
  'Mon': [{'apple': 'A', 'color': 'green'}, {'apple':'B', 'color':'yellow'}],
  'Tue': [{'apple': 'A', 'color': 'green'}, {'apple':'B', 'color':'yellow'}],
  'Wed': [],
  'Thu': [],
  'Fri': [{'banana': 'A', 'color': 'yellow'}],
  'Sat': [{'banana': 'A', 'color': 'yellow'}],
  'Sun': [{'banana': 'A', 'color': 'yellow'}]
};

var emptyKey = [];

function createId(o) {
  var values = [];
  
  for (let x in o) {
    if (o.hasOwnProperty(x)) {
      values.push(o[x])
    }
  }
  return Object.keys(o).sort().toString() + values.sort().toString();
}

var uniqueValues = [];

for (let d in original) {
  for (let b in original[d]) {
    let idx = createId(original[d][b]);
    if (uniqueValues.indexOf(idx) === -1) uniqueValues.push(idx);
  }

  if (Object.keys(original[d]).length === 0) emptyKey.push(d);
}

var result = {};

for (let u in uniqueValues) {
  let k = [];
  let o = null;
  
  for (let d in original) {
    for (let b in original[d]) {
      let idx = createId(original[d][b]);
      if (uniqueValues[u] === idx) {
        k.push(d);
        o = original[d][b];
      }
    }
  }
  
  if (k.length > 0) {
     result[k] = result[k] || [];
     result[k].push(o);
  }
}

if (emptyKey.length > 0) result[emptyKey] = [];

console.log(result)

However, some caveats of the solution:

  • As said, keys are string, not arrays, but anyway you can access them using arrays (because they have the toString() method).
  • The order in which the keys are printed is theoretical not guaranteed, and this is why I use the sort() method - also if all the major browsers will print them in the order they are inserted
Sign up to request clarification or add additional context in comments.

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.