0

I have two array, one is type of String and second one is number. How can I combine these conditionally as key value objects.

For example:

var fruits = [
  "Apple",
  "Banana" ,
  "Apricot",
  "Bilberry"
]

var count = [3,5,0,2]

I want to combine fruits and count array as key value object and which count is not 0

Expected:

var merge = [{"Apple":3},{"Banana" :5},{"Bilberry":2}]

What i have tried is:

var merge = _.zipObject(["Apple","Banana" ,"Apricot","Bilberry"], [3,5,0,2])

and result is:

{"Apple":3,"Banana":5 ,"Apricot":0,"Bilberry":2}
3
  • why not loop thorugh and do it yourself. i don't think there is any readymade function for this Commented Mar 22, 2018 at 10:00
  • @Abhishek, yes can do by loop, but its to fatigue :) Commented Mar 22, 2018 at 10:04
  • library will do same thing. Commented Mar 22, 2018 at 10:05

5 Answers 5

2

Try this vanilla js solution as well using filter, Object.values and map

var output = count.map((s, i) => ({
  [fruits[i]]: s
})).filter(s => Object.values(s)[0]);

Demo

var fruits = [
  "Apple",
  "Banana",
  "Apricot",
  "Bilberry"
];

var count = [3, 5, 0, 2];

var output = count.map((s, i) => ({
  [fruits[i]]: s
})).filter(s => Object.values(s)[0]);

console.log(output);

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

2 Comments

You might want to first map and only then filter, since the counts are now shifting one index away from the fruits.
@user3297291 You are right about it, I have updated the answer.
1

Create the object with _.zipObject(), and then use _.pickBy() to filter keys with 0 values.

Note: _.pickBy() accepts a callback. The default is identity, which will filter all falsy values (false, 0, null, undefined, etc...). If you want to filter just zeroes, supply another callback, for example (v) => v !== 0.

var fruits = ["Apple", "Banana", "Apricot", "Bilberry"];
var count = [3,5,0,2];

var result = _.pickBy(_.zipObject(fruits, count));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

With vanilla JS, you can use Array.reduce():

var fruits = ["Apple", "Banana", "Apricot", "Bilberry"];
var count = [3,5,0,2];

var result = fruits.reduce(function(r, f, i) {
  if(count[i]) r[f] = count[i];
  
  return r;
}, {});

console.log(result);

Comments

0

You can use map to create a new array of objects & filter to remove the undefined

The source of undefined is teh callback function is not returning any value when the count is 0

var fruits = [
  "Apple",
  "Banana",
  "Apricot",
  "Bilberry"
]

var count = [3, 5, 0, 2]
var newArr = count.map(function(item, index) {
  if (item !== 0) {
    return {
      [fruits[index]]: item
    }
  }
}).filter(function(item) {
  return item !== undefined;

})

console.log(newArr)

Comments

0

The two utility functions I think you're looking for are:

  • zip, to go from [ a, b ] + [ 1, 2 ] -> [ [ a, 1 ], [ b, 2 ] ]
  • fromPair to go from [ a, 1 ] -> { a: 1 }

Splitting the transformation in these two steps allows you to filter your list of key-value-pairs, which ensures you don't loose track of the link by index:

const valueFilter = ([k, v]) => v !== 0;

Possible implementations for those functions are:

const zip = (xs, ...others) =>
  xs.map(
    (x, i) => [x].concat(others.map(ys => ys[i]))
  );

const fromPair = ([k, v]) => ({ [k]: v });

With those utilities, you can do:

// Utils
const zip = (xs, ...others) =>
  xs.map(
    (x, i) => [x].concat(others.map(ys => ys[i]))
  );
  
const fromPair = ([k, v]) => ({ [k]: v });

// Data
const fruits = [ "Apple", "Banana", "Apricot", "Bilberry" ];
const counts = [3,5,0,2];

// App
const valueNotZero = ([k, v]) => v !== 0;

console.log(
  zip(fruits, counts)
    .filter(valueNotZero)
    .map(fromPair)
)

Comments

0

With simple forEach

var fruits = [
  "Apple",
  "Banana",
  "Apricot",
  "Bilberry"
]

var count = [3, 5, 0, 2];
var merge = [];

fruits.forEach((val, i) => {
  if (count[i]) { merge.push({ [val]: count[i] }) };
});

console.log(merge);

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.