Filtering and adding additional properties to array of objects Hi I am working on a complex application and currently adding two additional properties to objects that match the condition and returning it back. I was able to achieve the expected output, but just wanted to know if there is any other way which is more efficient than what I have tried.

Step 1 : Filtering the array to get only car objects.

Step 2 : Add firstlayer and lastlayer prop to car objects

Step 3 : 


If it is first car object in the filtered array then mark firstlayer 
as true.     If it is last car object in the filtered array then mark
lastlayer as true.


Step 4 : concat it with the other non-car objects 



Original array:

[{
  id: 10,
  name: "Truck",
  status: "Cancelled"
}, {
  id: 11,
  name: "Bus",
  status: "Approved"
}, {
  id: 12,
  name: "Car1",
  status: "Approved"
}, {
  id: 19,
  name: "Car2",
  status: "Cancelled"
}, {
  id: 13,
  name: "Car3",
  status: "Cancelled"
}]


Expected array:

[{
      id: 10,
      name: "Truck",
      status: "Cancelled"
    }, {
      id: 11,
      name: "Bus",
      status: "Approved"
    }, {
      id: 12,
      isFirstLayer: true,
      isLastLayer: false,
      name: "Car1",
      status: "Approved"
    }, {
      id: 19,
      isFirstLayer: false,
      isLastLayer: false,
      name: "Car2",
      status: "Cancelled"
    }, {
      id: 13,
      isFirstLayer: false,
      isLastLayer: true,
      name: "Car3",
      status: "Cancelled"
    }]


This is the code I have tried



var array = [
  {
    "name": "Truck",
    "status": "Cancelled",
    "id": 10
  },
  {
    "name": "Bus",
    "status": "Approved",
    "id": 11
  },
  {
    "name": "Car1",
    "status": "Approved",
    "id": 12
  },
  {
    "name": "Car2",
    "status": "Cancelled",
    "id": 19
  },
  {
    "name": "Car3",
    "status": "Cancelled",
    "id": 13
  }
];

var i=0;
var arrayLength=array.length;
var newArray = array.filter(function(a) {
  if((a.name !='Bus'&amp;&amp;a.name!='Truck')) 
  {   
      
      if(i==0){
    a.isFirstLayer=true;
          a.isLastLayer=false;
      }else if(i==arrayLength-i-1){
         a.isFirstLayer=false;
          a.isLastLayer=true;
      } else{
          a.isFirstLayer=false;
          a.isLastLayer=false;
      }
      i++;
  };
  return a
});

console.log(newArray);




https://jsfiddle.net/fierce_trailblazer/q2uvf06r/24/

Any suggestions to improve the code would be helpful
It may be a better idea to use a reducer to initially add the properties to a subset of the elements of the array. Finally you can change the last element from the new Array with a property isLastLayer. I used Array.find within the reducer lambda and a custom function findLast for finding the last array-element with property isLastLayer.



const result = document.querySelector("#result");
const log = (...txt) =&gt; result.textContent += txt.join("\n") + "\n";

// moved to function, so the relevant code is more visible
const array = getTestArray();

// find the last element using the predicate lambda
const findLast = (array, predicate) =&gt; {
  for (let i = array.length - 1; i &gt;= 0; --i) {
    if (predicate(array[i])) {
      return array[i];
    }
  }
};

// reduce the values, adding the layer props to 
// all elements where the name does not start 
// with 'bus' or 'truck'. Use Array.find within the 
// accumulated array to determine if isFirstLayer
// is already in the set of elements
let newArray = array.reduce((acc, value) =&gt; {
  if (/^(bus|truck)/i.test(value.name)) {
    return [...acc, value];
  }
  const isFirst = !acc.find(el =&gt; "isFirstLayer" in el);
  value = { ...value,
    isFirstLayer: isFirst,
    isLastLayer: false
  };
  return [...acc, value];
}, []);

// use findLast to find the last element with
// a property 'isLastLayer' in the array, and 
// change its value
findLast(newArray, el =&gt; "isLastLayer" in el).isLastLayer = true;

// let's see if it worked
log(JSON.stringify(newArray, null, 2));

function getTestArray() {
  return [{
      "name": "Truck",
      "status": "Cancelled",
      "id": 10
    },
    {
      "name": "Bus",
      "status": "Approved",
      "id": 11
    },
    {
      "name": "Car1",
      "status": "Approved",
      "id": 12
    },
    {
      "name": "Car2",
      "status": "Cancelled",
      "id": 19
    },
    {
      "name": "Car3",
      "status": "Cancelled",
      "id": 13
    }
  ];
}
&lt;pre id="result"&gt;&lt;/pre&gt;




It can also be done without the extra findLast function



const result = document.querySelector("#result");
const log = (...txt) =&gt; result.textContent += txt.join("\n") + "\n";
const array = getTestArray();
let accumulator = {
  newArr: [], 
  // track first/last
  firstLayerSet: false,
  lastLastLayer: null
};
const addPropsReducer = (acc, value, i) =&gt; {
  if (/^(bus|truck)$/i.test(value.name)) {
    return {
      newArr: [...acc.newArr, value]
    };
  }
  value = { ...value,
    isFirstLayer: !acc.firstLayerSet,
    isLastLayer: false
  };
  return {
    ...acc,
    newArr: [...acc.newArr, value],
    firstLayerSet: true,
    lastLayerIndex: i
  };
};

let newArray = array.reduce(addPropsReducer, accumulator);
newArray.newArr[newArray.lastLayerIndex].isLastLayer = true;

// ditch tracking values
newArray = newArray.newArr;

log(JSON.stringify(newArray, null, 2));

function getTestArray() {
  return [{
      "name": "Truck",
      "status": "Cancelled",
      "id": 10
    },
    {
      "name": "Bus",
      "status": "Approved",
      "id": 11
    },
    {
      "name": "Car1",
      "status": "Approved",
      "id": 12
    },
    {
      "name": "Car2",
      "status": "Cancelled",
      "id": 19
    },
    {
      "name": "Car3",
      "status": "Cancelled",
      "id": 13
    }
  ];
}
&lt;pre id="result"&gt;&lt;/pre&gt;




Play with this code in jsFiddle.