1

I have an object / associate array which has name and values. I am trying to create another array based on the keys of the array which has values.

This is the array

0: {country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42}  
1: {country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}

new array should skip the first element and start with next element and generate an array from keys which has values. result array

{"Biomass","Gas","Coal"}

Biomass, Coal and Gas has values therefore should appear in the new array. country is the first element and shouldn't appear. I tried google, but couldn't help.

var ks = Object.keys(output);
console.log(ks);

this return only 0 and 1

1
  • Why would skip the first element? there is a key named Gas that have a value on the first object. Also, do you want an array of not null key for every object on the original array or only one array for the complete original array that collect all the keys that are not null in some of the objects? Commented Feb 15, 2019 at 2:43

7 Answers 7

3

You can use reduce and Set

let arr = [ {country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42},{country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}]

let op = arr.reduce((op,inp)=>{
  Object.keys(inp).forEach((e,index)=>{
    if(!op.has(inp[e]) && index !== 0 && inp[e]){
      op.add(e)
    }
  })
  return op;
},new Set())

console.log([...op])

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

1 Comment

Based on OP's described output and this quote: "Biomass, Coal and Gas has values therefore should appear in the new array." - it sounds like Cogeneration shouldn't be included as neither record has a value for it.
2

Object.keys as applied to the main array would only be referring to the 'keys' of the array, i.e. the zero-based index of the objects, which is why you are getting 0 and 1.

If you want to get the keys of the objects contained within the array, you should do something like this:

let energySources = array.reduce((acc, item) => {
  for (let key in item) {
    if (item[key] !== null && key !== "country") {
      acc.push(key);
    }
  }
  return acc;
}, []);

let uniqueValues = [...new Set(energySources)];

5 Comments

Thanks, this gives me the result, but it shows duplicate keys
That's why you have to run this line: let uniqueValues = [...new Set(energySources)];
It print "Gas" twice.
You can do this: let uniqueValues = energySources.reduce((acc,item) => acc.includes(item) ? acc : [...acc, item], [])
My mistake, It was perfectly working. Thanks a lot and appreciate it.
0

const input = [
  {country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42} ,
  {country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}
];

const output = input.reduce((accu, {country, ...rest}) => {
  Object.keys(rest).forEach((key) => {
    if(rest[key] && !accu.includes(key)) {
      accu.push(key);
    }
  });
  return accu;
}, []);

console.log(output);

Comments

0

Here you have another approach with reduce() that will generate an object with true values for a key that has a value. Finally, we generate you array using Object.keys() on it.

const input = [
  {country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42},
  {country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}
];

let res = input.reduce((acc, curr) =>
{
    Object.keys(curr).forEach(
        (k, i) => !acc[k] && i > 0 && curr[k] && (acc[k] = true)
    );
    return acc;
}, {});

res = Object.keys(res);
console.log(res);

Comments

0

var objArr = [
{country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42} ,
 {country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}
]

var result = [];

function filterArr(item) {
	for(var j in item) {
  	if(j !== 'country') {
    	if(item[j]) {
      	result.push(j);
      }
    }
  }
}

for(var i of objArr) {
filterArr(i);
}

for(var p of result) {
	console.log(p);
}

Comments

0
  1. Iterate through the array with arr.reduce().

  2. With each iteration, get the object's keys using getOwnPropertyTypes().

  3. filter() out any keys whose value is null, key is country, or key is already included in our output.

const arr = [ {country: "AFG", Biomass: null, Coal: null, Cogeneration: null, Gas: 42},{country: "AGO", Biomass: 10, Coal: 20, Cogeneration: null, Gas: null}];

let result = arr.reduce((output, i) => [
  ...output, 
  ...Object.getOwnPropertyNames(i)
      .filter(k => i[k] && k !== "country" && !output.includes(k))
  ], []);

console.log(result);

While iterating, we add the current results to our output using spread syntax. E.g., [...arr1, ...arr2] would combine the contents of arr1 and arr2.

Comments

-2

Is this what you mean or did I missunderstand?

array1.forEach(function(item,index){ array2[item] = index;});

1 Comment

This does not answer the original question and would be better as a comment.

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.