Grant mitchell
Grant mitchell

Reputation: 529

javascript array push keeps repeating it self cant find out why

I cant figure out why this arrayUnd gets repeated key values. ive been on this for three weeks. I must be doing somehthing stupid. I know they are loops. but everything works except the push. it logs when the key repeats and stuff. but it somehow is adding it to it? very confusing. Heres my Javascript


var array = [
              {"size":["12","22"]},
              {"color":["blue"]},
              {"design":["flower-blue"]},
                {"size":["12","22","44"]},
              {"color":["red"]},
              {"design":["flower-blue"]}
          ]
//output array
arrayUnd=[           
  {"color":["red"]}
]

//is array?
console.log(  Array.isArray(array))
function pusher(obj){
arrayUnd.push(obj)
}

function isRepeat(key,value,obj){
 // console.log(key[0])
  
  for (let item=0; item < arrayUnd.length; item++ ){
    
    if ( arrayUnd[item].hasOwnProperty(key)){
      console.log("key: " + key)
        console.log("yes")
      console.log(arrayUnd)
    }
    else{
            console.log("keyno: " + key)

        console.log("no")
        //pusher(obj)
      if ( arrayUnd[item].hasOwnProperty(key) === false){
      pusher(obj)
      }
            console.log(arrayUnd)

        }
    }
  
}
array.forEach((obj)=>{
  var a= Object.keys(obj)
    var b= Object.values(obj)
isRepeat(a,b,obj)
})

console.log(arrayUnd)

Upvotes: 0

Views: 493

Answers (4)

Sven.hig
Sven.hig

Reputation: 4519

The reason your code keeps pushing object to arrayUnd it's because when it iterates through the array it checks for the array key if its present if not it pushes it to arrayUnd, now you have 2 problems first you are not actually checking for the array key to match you comparing object so you will always get false , and second is that each time you push to the array the length of your array grow and so the number of iterations increases

you can achieve this in two lines of code

var array = [
  {"size":["12","22"]},
  {"color":["blue"]},
  {"design":["flower-blue"]},
  {"size":["12","22","44"]},
  {"color":["red"]},
  {"design":["flower-blue"]}
]
//output array
arrayUnd=[           
{"color":["red"]}
]

array.forEach(p=>Object.entries(p).forEach(p=>{
  !arrayUnd.some(o=>o.hasOwnProperty(p[0])) ? arrayUnd.push({[p[0]]:p[1]}):null
}))
console.log(arrayUnd)

Upvotes: 1

Ziaullhaq Savanur
Ziaullhaq Savanur

Reputation: 2338

var inpAry = [
    { "size": ["12", "22"] },
    { "color": ["blue"] },
    { "design": ["flower-blue"] },
    { "size": ["12", "22", "44"] },
    { "color": ["red"] },
    { "design": ["flower-blue"] }
];

var opAry = [
    { "color": ["red"] }
];

inpAry.forEach(inpAryElem => {
    var ipAryElemKeys = Object.keys(inpAryElem);
    var ipAryElemVals = Object.values(inpAryElem);
    ipAryElemKeys.forEach((ipAryElmKey,ipAryElemKyIdx) => {
        var isKeyPresent = false;
        opAry.forEach(opAryElem => {
            if(opAryElem[ipAryElmKey]) {
                isKeyPresent = true;
                opAryElem[ipAryElmKey].push(...ipAryElemVals[ipAryElemKyIdx]);
            }
        });
        if(!isKeyPresent) {
            opAry.push({[ipAryElmKey]:ipAryElemVals[ipAryElemKyIdx]});
        }
    })
});

console.log(opAry);

Upvotes: 0

user120242
user120242

Reputation: 15268

Your loop is checking all objects to see if they don't match. At least one of them won't match, so it will try to push that many times. You need to check all elements, and after checking them all for existence decide if you want to push or not.
Current logic is equivalent to: if anything in arrUnd doesn't match, push me each time I check.
some works here, because it checks if anything matches, and returns true or false, which you can then use to decide if you want to push or not (only once, after I've found if anything in the array matches, deciding using the final result).

Using some to check if any other element with same key exists. Push if nothing found.

var array = [{
    "size": ["12", "22"]
  },
  {
    "color": ["blue"]
  },
  {
    "design": ["flower-blue"]
  },
  {
    "size": ["12", "22", "44"]
  },
  {
    "color": ["red"]
  },
  {
    "design": ["flower-blue"]
  }
]
//output array
arrayUnd = [{
  "color": ["red"]
}]

//is array?
console.log(Array.isArray(array))

function pusher(obj) {
  arrayUnd.push(obj)
}

function isRepeat(key, value, obj) {
  if(!arrayUnd.some(x => x.hasOwnProperty(key[0])))
    arrayUnd.push(obj)
}
array.forEach((obj) => {
  var a = Object.keys(obj)
  var b = Object.values(obj)
  isRepeat(a, b, obj)
})

console.log(arrayUnd)

Upvotes: 1

zeterain
zeterain

Reputation: 1140

You are passing an array to isRepeat instead of the key and value of the object.

Object.keys() returns an array, even if the object only has one key.

When you check if ( arrayUnd[item].hasOwnProperty(key) === false), arrayUnd[item].hasOwnProperty(key) will always be false, so the object will always get pushed to your array.

You can fix this by accessing the first key and value of each object:

array.forEach((obj)=>{
  var a= Object.keys(obj)
    var b= Object.values(obj)
isRepeat(a[0],b[0],obj)
})

Upvotes: 1

Related Questions