2

I have following array of objects.

[{"rId":24,"gId":40,"sId":20,"disabled":false},
 {"rId":24,"gId":40,"sId":19,"disabled":false},
 {"rId":24,"gId":40,"sId":50,"disabled":false},
 {"rId":24,"gId":40,"sId":20,"disabled":true},
 {"rId":24,"gId":40,"sId":19,"disabled":true},
 {"rId":24,"gId":40,"sId":50,"disabled":true},
 {"rId":24,"gId":39,"sId":18,"disabled":false}]

In which some records are antithesis ex. 1st element and 4th which has same rId, gId, and sId but disabled flag is opposite. I want to eliminate all such records.

My expected array is {"rId":24,"gId":39,"sId":18,"disabled":false} (eliminate all antithesis records)

I tried following code but it is giving me wrong output.

arrOfObj=[{"rId":24,"gId":40,"sId":20,"disabled":false},
 {"rId":24,"gId":40,"sId":19,"disabled":false},
 {"rId":24,"gId":40,"sId":50,"disabled":false},
 {"rId":24,"gId":40,"sId":20,"disabled":true},
 {"rId":24,"gId":40,"sId":19,"disabled":true},
 {"rId":24,"gId":40,"sId":50,"disabled":true},
 {"rId":24,"gId":39,"sId":18,"disabled":false}]


$.each(arrOfObj,function (index1,firstObj) {
    $.each(arrOfObj,function (index2,secondObj) {
        if(index1>= index2){
            return true;
        }
        var areObjAntithesis=firstObj.rId===secondObj.rId && firstObj.gId===secondObj.gId
           && firstObj.sId===secondObj.sId && firstObj.disabled!==secondObj.disabled;

        if(areObjAntithesis){
            arrOfObj.splice(index1,1);
            arrOfObj.splice(index2,1)
            return false;
        }
    })
})

Is there any elegant way to achieve expected output ?

5 Answers 5

1

You could do this with map() and filter()

var data = [{"rId":24,"gId":40,"sId":20,"disabled":false},
 {"rId":24,"gId":40,"sId":19,"disabled":false},
 {"rId":24,"gId":40,"sId":50,"disabled":false},
 {"rId":24,"gId":40,"sId":20,"disabled":true},
 {"rId":24,"gId":40,"sId":19,"disabled":true},
 {"rId":24,"gId":40,"sId":50,"disabled":true},
 {"rId":24,"gId":39,"sId":18,"disabled":false}]
 
var ar = data.map(function(e) {
  return e.rId + '|' + e.gId + '|' + e.sId;
});
 
var result = data.filter(function(e) {
  var key = e.rId + '|' + e.gId + '|' + e.sId;
  return ar.indexOf(key) == ar.lastIndexOf(key);
});

console.log(result)

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

Comments

0

Use http://underscorejs.org/#where and do like that:

var newArrOfObj=_.where(arrOfObj, {disabled:true});

Comments

0

You can use multiple array.filter and check count and only return elements which have more than 1 value and if values are same or have only one value

var data = [{"rId":24,"gId":40,"sId":20,"disabled":false},
 {"rId":24,"gId":40,"sId":19,"disabled":false},
 {"rId":24,"gId":40,"sId":50,"disabled":false},
 {"rId":24,"gId":40,"sId":20,"disabled":true},
 {"rId":24,"gId":40,"sId":19,"disabled":true},
 {"rId":24,"gId":40,"sId":50,"disabled":true},
 {"rId":24,"gId":39,"sId":18,"disabled":false}]

var result = data.filter(function(outer){
  var disablesValues = []
  
  var _r = data.filter(function(inner){
    if(inner.gId === outer.gId && inner.sId === outer.sId){
      if(disablesValues.indexOf(inner.disabled) < 0)
        disablesValues.push(inner.disabled);
      return true;
    }
  });
  
  return _r.length === 1 || disablesValues.length === 1
});

console.log(result)

Comments

0

Here is functional programming style ES6 solution, which will deal with more repetitions as well, counting how the number of disabled and enabled objects balance annihilate each other:

function eliminateOpposites(arr) {
    return [...arr
        .map( o => ({ o, k: JSON.stringify({ rId:o.rId, gId:o.gId, sId:o.sId }) }) )
        .reduce( (acc, o) => acc.set(o.k, (acc.get(o.k) || 0)+ (+o.o.disabled || -1)),
                             new Map() )]
        .filter( ([k, balance]) => balance )
        .map( ([k, balance]) => Object.assign(JSON.parse(k), {disabled: balance>0}));
}

// Sample data
var arrOfObj=[
 {"rId":24,"gId":40,"sId":20,"disabled":false},
 {"rId":24,"gId":40,"sId":19,"disabled":false},
 {"rId":24,"gId":40,"sId":50,"disabled":false},
 {"rId":24,"gId":40,"sId":20,"disabled":true},
 {"rId":24,"gId":40,"sId":19,"disabled":true},
 {"rId":24,"gId":40,"sId":50,"disabled":true},
 {"rId":24,"gId":39,"sId":18,"disabled":false}]
 
console.log(eliminateOpposites(arrOfObj));

It makes use of hashing, which leads to a O(n) algorithm instead of O(n²), which is the case with indexOf-style solutions.

JSON.stringify and JSON.parse are used to compose and decompose the composite key values. The string version serves as key in a Map, in which each entry logs a count of disabled versus enabled occurrences of the same key. The .filter() call kicks out the cases where the count of disabled and enabled occurrences is the same (could be 2 versus 2), and the final .map() turns the kay/value array back to the expected format.

Comments

0

You could two loops, one for collecting and one for filtering the array.

var data = [{ "rId": 24, "gId": 40, "sId": 20, "disabled": false }, { "rId": 24, "gId": 40, "sId": 19, "disabled": false }, { "rId": 24, "gId": 40, "sId": 50, "disabled": false }, { "rId": 24, "gId": 40, "sId": 20, "disabled": true }, { "rId": 24, "gId": 40, "sId": 19, "disabled": true }, { "rId": 24, "gId": 40, "sId": 50, "disabled": true }, { "rId": 24, "gId": 39, "sId": 18, "disabled": false }],
    hash = Object.create(null),
    getKey = function (o) { return ["rId", "gId", "sId"].map(function (k) { return o[k]; }).join('|'); },
    result;

data.forEach(function (a) {
    var key = getKey(a);
    hash[key] = (hash[key] || 0) + (a.disabled || -1);
});

result = data.filter(function (a) {
    return hash[getKey(a)];
});

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

ES6 with Array#find

var data = [{ "rId": 24, "gId": 40, "sId": 20, "disabled": false }, { "rId": 24, "gId": 40, "sId": 19, "disabled": false }, { "rId": 24, "gId": 40, "sId": 50, "disabled": false }, { "rId": 24, "gId": 40, "sId": 20, "disabled": true }, { "rId": 24, "gId": 40, "sId": 19, "disabled": true }, { "rId": 24, "gId": 40, "sId": 50, "disabled": true }, { "rId": 24, "gId": 39, "sId": 18, "disabled": false }],
    result = data.filter(a =>
        !data.find(b => ["rId", "gId", "sId"].every(k => 
            a[k] === b[k]
        ) && a.disabled !== b.disabled));

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

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.