0

I'm working with angular4 and I've been having a lot of trouble trying to display some elements of an array in my view. I got this enter image description here

the number of elements can change according to the current month so if it was February it would be only M01 and M02 in the array. I've been trying to loop it in for loop but I can't seem to get it right. any ideas on how to do it?

I'd like to get something like this, all values that start with "M" in a single property

[0:  M: [...]
     cod_item:...
     cod_condominio:...
...
]

it doesn't matter if it is an array or object as long as i can loop that element to show it in my view.

9
  • Not certain what requirement is? Are you trying to get only the elements of the array when the property name begins with "M"? Commented Nov 6, 2017 at 2:03
  • 1
    That is a poor design, unless you always want to loop over every Object and test for its properties. Always fix your design, if possible, first. Commented Nov 6, 2017 at 2:12
  • @guest271314 yes, that's what I'm trying to do. PHPglue unfortunately I can't change the design, actually its messier than that but i managed to reduced it to work with it Commented Nov 6, 2017 at 2:23
  • What you've circled isn't elements in an array, it is some of the properties of the object that is the first element of the outer array. Commented Nov 6, 2017 at 2:27
  • yes, I'm sorry for misleading. its an array of 5 objects all of them have the same structure. Commented Nov 6, 2017 at 2:29

5 Answers 5

1

You can use nested loops to check is the current property begins with "M", set the properties, values to a an object, push the object to an array

const arr = [{M01:1, M02:2, M03:3, A:4, B:5}, {M04:6, M05:7}];

let res = [];

let match = "M";

for (let o of Object.values(arr)) {
  const curr = {};
  for (let [key, prop, [k] = key] of Object.entries(o)) {
    if (k === match) {
       curr[key] = prop;
    }
  }
  res.push(curr);
}

console.log(res);

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

3 Comments

awesome bro, this gives me properties that start with "M", now I need to push it to the main object I'm going to try that :)
Are you also trying to delete the property from the original object and create a property "M" which contains the array where the object having "M" properties is stored?
yes, I don't mind if the original properties stayed as long as I add a new property M which contains "M01", "M02", "M03"...
1

If you want just the properties starting with "M", you can use reduce to loop over all the objects and collect just those elements:

// data
var arr = [{}, {
  M0:'foo',
  M1:'bar',
  M2:'fum',
  blah:'blah'
  }, {
  M0:'foo',
  blah:'blah',
  gee:'gee'
  }
];

// Build an array of objects only containing
// properties starting with "M" followed by digits
var result = arr.reduce(function(acc, obj) {
  var o = {};

  // Loop over object keys
  Object.keys(obj).forEach(function(key){

    // Collect those matching the required pattern
    if (/^M\d+$/.test(key)) {
      o[key] = obj[key];
    }
  });

  // If found some properties, push into accumulator
  if (Object.keys(o).length) acc.push(o);

  return acc;
}, []);

// Show results
console.log(result)

// Concise
var r = arr.reduce((acc, obj) => {
  var o = {};
  Object.keys(obj).forEach(key => {
    if (/^M\d+$/.test(key)) o[key] = obj[key];
  });
  if (Object.keys(o).length) acc.push(o);
  return acc;
}, []);

console.log(r)

Comments

0

This below solution is rookie way of doing it. But it would be technical debt.

The below snippet will give you array of elements based on current month.

var d = new Date();
var n = d.getMonth();

a =[]
for(i=1;i<=n;i++){
a.push('M'+('0'+(i).toString()).slice(-2))
}
console.log(a)

in angular template while looping over the object check if the key exist in the array

1 Comment

I'm sorry for misleading you, I edited my question for better understanding.
0

If you have access to backend, the best option is to change the response from your backend, it's not a good idea to refactor the response in front-end. So if you have access just change the response to get your needed items in a separated list.

But if you using a third party and have no access to backend code, you can use something like this to get only values of items which start with "M" :

var a = [
 {
   "M01": 1,
   "M02": 2,
   "code": 44
 },
 {
   "M01": 13,
   "M02": 4,
   "code": 3
 },{
   "M01": 4,
   "M02": 21,
   "code": 11
 }
]

 var t = [];

 for(var i in a){
    for(var j in a[i]){
         if (j[0]=="M") t.push(a[i][j])
     }  
 console.log(t);// it will only have values of items which start with "M"
}

https://jsfiddle.net/f772o781/1/

1 Comment

for..in over arrays is not recommended, especially without an own property test.
0

const matchStr = (str) => {
  const matchArr = str.match(/^M(\d\d)/i);
  if (matchArr) return +matchArr[1];
  return 0;
}

const extractor = (month) => (dataArr) => {
  return dataArr.map((data) => {
    const tempObj = {};
    const keys = Object.keys(data);
    keys.forEach((key) => {
      if (matchStr(key) && matchStr(key) > month) return;
      tempObj[key] = data[key];
    });
    return tempObj
  });
}

const yourData = [{
    M01: '35238',
    M02: '123121',
    M03: '132222',
    cod_item: '1',
    filtro: 'saldo'
  },
  {
    M01: '35238',
    M02: '123121',
    M03: '132222',
    cod_item: '1',
    filtro: 'saldo'
  },
  {
    M01: '35238',
    M02: '123121',
    M03: '132222',
    cod_item: '1',
    filtro: 'saldo'
  }
];

console.log(extractor(2)(yourData));

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.