0

I have an array like this:

var array = [
      {"id":"A","type":"blue","rng":"50"},
      {"id":"A","type":"blue","rng":"75"},
      {"id":"A","type":"grey","rng":"76"},

      {"id":"B","type":"blue","rng":"50"},
      {"id":"B","type":"grey","rng":"85"},
      {"id":"B","type":"grey","rng":"86"},

      {"id":"C","type":"blue","rng":"50"},
      {"id":"C","type":"grey","rng":"65"}
    ]

Note: Objects arranged in random order.

I need away to filter out the duplicate "id":"*","type":"blue" and "id":"*","type":"grey" with the higher "rng".

So the final result is:

var result = [
      {"id":"A","type":"blue","rng":"50"},
      {"id":"A","type":"grey","rng":"76"},

      {"id":"B","type":"blue","rng":"50"},
      {"id":"B","type":"grey","rng":"86"},

      {"id":"C","type":"blue","rng":"50"},
      {"id":"C","type":"grey","rng":"65"}
    ]

I'm keen on using underscore but any other solution is welcome too.

0

2 Answers 2

2

You could use a hash table and a combined key as reference to the index.

var data = [{ id: "A", type: "blue", rng: "50" }, { id: "A", type: "blue", rng: "75" }, { id: "A", type: "grey", rng: "76" }, { id: "B", type: "blue", rng: "50" }, { id: "B", type: "grey", rng: "85" }, { id: "B", type: "grey", rng: "86" }, { id: "C", type: "blue", rng: "50" }, { id: "C", type: "grey", rng: "65" }],
    result = data.reduce(function (hash) {
        return function (r, o) {
            var key = ['id', 'type'].map(function (k) { return o[k]; }).join('|');
            if (!(key in hash)) {
                hash[key] = r.push(o) - 1;
            } else if (r[hash[key]].rng < o.rng) {
                r[hash[key]] = o;
            }
            return r;
        };
    }(Object.create(null)), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

1

You can use forEach() loop and one object as thisArg parameter to check if object with same id|type exists.

var array = [{"id":"A","type":"blue","rng":"50"},{"id":"A","type":"blue","rng":"75"},{"id":"A","type":"grey","rng":"76"},{"id":"B","type":"blue","rng":"50"},{"id":"B","type":"grey","rng":"85"},{"id":"B","type":"grey","rng":"86"},{"id":"C","type":"blue","rng":"50"},{"id":"C","type":"grey","rng":"65"}]
    
var result = []
array.forEach(function(e) {
  // Create key with id and type
  var key = e.id + '|' + e.type;
  // Check if key exists in this object and if it doesn't create property with value of current value and push that value to result array
  if(!this[key]) this[key] = e, result.push(this[key])
  else {
    // Otherwise check if rng of current element is < of rng of previous object with same key and if it is set rng to rng of current object
    if(e.rng < this[key].rng) this[key].rng = e.rng
  }
}, Object.create(null))
    
 console.log(result)

2 Comments

Thank you. I don't fully understand your solution but it works fine for me. I chose it because it's the shortest at this point, regardless of efficiency and elegancy.
@Radoslav T. You're welcome, i added some explanation i hope it helps.

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.