0

I have got the following code that returns an object based on a filter i want to convert this to functional programming using map, filter.

var records_object =  {
    "record": [
      "analog",
      "laser",
      "monochrome",
      "digital"
    ],
    "vcd": [
      12,
      3,
      6,
      0
    ],
    "dvd": [
      1,
      0,
      0,
      16
    ]
  }
  
  var arr_idx = [];
for (i = 0; i < records_object.record.length; i++) {
  if (records_object.record[i].match(/digital/i) != null||
  records_object.record[i].match(/analog/i) != null) {
    arr_idx.push(i);
  }
}

for (el in records_object) {
  records_object[el] = records_object[el].filter(function (x, i) {
    return arr_idx.indexOf(i) != -1;
  });
}

console.log(records_object);

so far i was able to do this , now i am stuck

const getIndex = (data) => {
  return data.record
.map((e, i) =>
  e.includes("analog") || e.includes("digital") ? i : undefined
)
.filter((x) => x !== undefined);
};
3
  • 1
    You are doing a lot in single line of code. To find the cause of your problem you should go step by step. First create a normal function and put each part on a separate line using variables. Then you can console.log the output of each line, to find out where your mistake is. Commented Nov 4, 2020 at 6:22
  • can we use other prototype methods like reduce? Commented Nov 4, 2020 at 6:36
  • @varun, still trying to figure out the reduce function, any ideas? Commented Nov 4, 2020 at 6:40

3 Answers 3

1

You can do this,

var records_object =  {
    "record": [
      "analog",
      "laser",
      "monochrome",
      "digital"
    ],
    "vcd": [
      12,
      3,
      6,
      0
    ],
    "dvd": [
      1,
      0,
      0,
      16
    ]
  }
  
  let arrayIndexes = records_object.record.map((item, index) => {
       if(item.match(/digital/i) != null || item.match(/analog/i) !== null) {
          return index;
       }
  }).filter(item => item !== undefined);

  let newObject = Object.keys(records_object).reduce((prev, key) => {
       prev[key] = records_object[key].filter((item, index) => arrayIndexes.includes(index));
       return prev;
  }, {});
console.log(newObject);

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

3 Comments

thank you @sabbir.alam, i am looking for a more functional approach maybe using reduce?
I don't know how reduce will make it more functional than it is with map. Anyway I have converted my code to use reduce method.
Thank you for @sabbir.alam, actually i was hoping both map function and reduce is clarified in this example. appreciated much
1

The problem was with filter.

when you are running map it returns array [0, undefined, undefined, 3] and that array is being filtered and as you are using filter(x => x), this will iterate through the returned array and remove all the falsy values and return the resulting array.

In [0, undefined, undefined, 3]'s case, only 3 is the truthy value and that's why you are getting only [3] as 0 too is falsy.

You can modify your code slightly to get this resolved.

var records_object = {
  record: ["analog", "laser", "monochrome", "digital"],
  vcd: [12, 3, 6, 0],
  dvd: [1, 0, 0, 16],
};

const getIndex = (data) => {
  return data.record
.map((e, i) =>
  e.includes("analog") || e.includes("digital") ? i : undefined
)
.filter((x) => x !== undefined);
};

console.log(getIndex(records_object));

2 Comments

this really helped me understand the filter and map function
Glad it was helpful, happy coding.
1

Here is the solution using reduce and filter function. I've saved the result in new object.

var records_object = {
  "record": [
    "analog",
    "laser",
    "monochrome",
    "digital"
  ],
  "vcd": [
    12,
    3,
    6,
    0
  ],
  "dvd": [
    1,
    0,
    0,
    16
  ]
};

const matchByString = ['analog', 'digital'];

const isMatch = (el, stringElements) => stringElements.some((strEl) => el.match(new RegExp(strEl, 'i')) != null);

const filterByIndex = records_object.record.reduce((acc, el, index) => isMatch(el, matchByString) ? [...acc, index] : acc, [])

const result = {};
Object.keys(records_object).forEach(i => result[i] = records_object[i].filter((el, i) => filterByIndex.includes(i)));

console.log(result)

2 Comments

how can i change the includes to match in your filterByIndex function if i were to look for part of a string that matches the array?
We have to use regex and iterate the array of string, I'll update that in my answer

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.