Oam Psy
Oam Psy

Reputation: 8663

Grouping Objects In Array Based On Property Name

I have an array with a list of objects:

var myArray = [
    {"cartItems": {"paramA1": 25, "paramA2": 35}},
    {"cartShippingCost": {"paramB1": 4, "paramB2": 152, "paramB3": 536, "paramB4": 56}},
    {"cartSpecialRequirements": {"paramC1": 432}},
    {"cartPostage": {"paramD1": 56, "paramD2": 6537}},
    {"uid": {"paramE1": 545}},
    {"tel": 7778798548}
];

How can i loop through the above and group objects that contain 'cart' and ones that don't?

I know i need to create 2 temp obj's e.g.

var cartObj;
var nonCartObj;

And perform a .push in to each of these if the condition is met.

Tried:

for(var i in myArray) { 
    if (i == 'cart') {
        console.log('cart match found');
    }
}

Update:

Using Object.keys always hitting else case:

var key = Object.keys(item);

if (key.indexOf("cart") !== -1) {
    alert(key + " contains cart");
} else {
    alert(key + " doesnt contain cart");
}

Upvotes: 1

Views: 79

Answers (4)

Calvin Belden
Calvin Belden

Reputation: 3104

You can use Array.prototype.filter to create a new array where each item satisfies some condition:

var cartItems = myArray.filter(hasCartProperty);
var nonCartItems = myArray.filter(function (x) { return !hasCartProperty(x); });


// Checks to see if any of the object's keys contain the text 'cart'
function hasCartProperty(x) {
    return Object.keys(x).some(function (x) {
        return x.indexOf('cart') > -1;
    });
}

Upvotes: 3

Nina Scholz
Nina Scholz

Reputation: 386560

A solution with one loop without Array#filter().

var myArray = [{ "cartItems": { "paramA1": 25, "paramA2": 35 } }, { "cartShippingCost": { "paramB1": 4, "paramB2": 152, "paramB3": 536, "paramB4": 56 } }, { "cartSpecialRequirements": { "paramC1": 432 } }, { "cartPostage": { "paramD1": 56, "paramD2": 6537 } }, { "uid": { "paramE1": 545 } }, { "tel": 7778798548 }],
    grouped = function (array) {
        var r = { cart: [], nonCart: [] };
        array.forEach(function (a) {
            Object.keys(a).some(function (k) {
                if (k.indexOf('cart') === 0) {
                    return r.cart.push(a);
                }
            }) || r.nonCart.push(a);
        });
        return r;
    }(myArray);

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');

Upvotes: 0

Jack A.
Jack A.

Reputation: 4443

The JavaScript Array object has a filter function that can be used for this.

The tricky part is the function that performs the filtering. One way to do that is to iterate the keys in the objects to detect which ones contain "cart" keys.

var myArray = [
    {"cartItems": {"paramA1": 25, "paramA2": 35}},
    {"cartShippingCost": {"paramB1": 4, "paramB2": 152, "paramB3": 536, "paramB4": 56}},
    {"cartSpecialRequirements": {"paramC1": 432}},
    {"cartPostage": {"paramD1": 56, "paramD2": 6537}},
    {"uid": {"paramE1": 545}},
    {"tel": 7778798548}
];

var cartObj = myArray.filter(function (x) { return isCart(x); });
var nonCartObj = myArray.filter(function (x) { return !isCart(x); });

console.log("cart count = " + cartObj.length + ", non-cart count = " + nonCartObj.length);

function isCart(x) {
  for (var key in x) {
    if (x.hasOwnProperty(key) && key.startsWith("cart")) {
      return true;
    }
  }
  return false;
}

Upvotes: 0

Jack Guy
Jack Guy

Reputation: 8523

Loop through each item of the array, and then inside that loop iterate over the object keys to find what you're looking for

var result = [];
myArray.forEach(function (item) {
  for (var key in item) {
     if (key.indexOf('cart') !== -1) {
        result.push(item);
     }
  }
});

console.log(result);

Upvotes: 2

Related Questions