Home > database >  javascript place array on key
javascript place array on key

Time:12-02

I have this simple array:

const arr = [
  {
    "id": 2,
    "color": "red"
  },
  {
    "id": 1,
    "color": "blue"
  },
  {
    "id": 2,
    "color": "yellow"
  },
];

I want to create a hash map where I want to add new colors on that key.

E.g I want to added color: green on id: 3

Now here you can see there is no id: 3

Now here I am expecting:

{
    2: [{color: "red"}]
    1: [{color: "blue"}, {color: "yellow"}],
    3: [{color: "green"}]
}

Now if I want to add color: brown on id: 2

In that case I am expecting:

{
    2: [{color: "red"}, {color: "brown"}]
    1: [{color: "blue"}, {color: "yellow"}],
    3: [{color: "green"}]
}

I have created a Playground:

const arr = [
  {
    "id": 2,
    "color": "red"
  },
  {
    "id": 1,
    "color": "blue"
  },
  {
    "id": 2,
    "color": "yellow"
  },
];

function addItem(id: number, colors: any) {
    let newArr = {[id]: colors};
  arr.forEach(function (obj) {

    newArr[obj.id].push({id: obj.color});
  });
  return newArr;
}

console.log(addItem(3, [{color: "green"}]))
console.log(addItem(1, [{color: "brown"}]))

Here I also want to avoid duplicates

CodePudding user response:

const arr = [{
    "id": 2,
    "color": "red"
  },
  {
    "id": 1,
    "color": "blue"
  },
  {
    "id": 2,
    "color": "yellow"
  },
];

const grouped = arr.reduce((groups, current) => {
  if (!(current.id in groups)) {
    groups[current.id] = []
  }
  groups[current.id].push({
    color: current.color
  })
  return groups
}, {})

addItem(3, {
  color: "green"
})

addItem(1, {
  color: "brown"
})

console.log(grouped)

function addItem(id, item) {
  if (!(id in grouped)) {
    grouped[id] = []
  }
  grouped[id].push(item)
}

CodePudding user response:

function test(id, color) {
                for (var i = 0; i < arr.length; i  ) {
                  if (arr[i].id == id) {
                    arr[i].color.push(color)
                  }
                }
              }

Basically it will loop through your array, and if its id matches, it will add your color.

CodePudding user response:

Following code can help you to solve this problem

const hashMap = new Map([
  [1, [{ color: "red" }]],
  [2, [{ color: "blue" }]],
  [3, [{ color: "yellow" }]],
]);

function addItem(id, colors) {
  hashMap.set(
    id,
    hashMap.has(id) ? [...hashMap.get(id).concat(colors)] : colors
  );

  return hashMap;
}
console.log(hashMap);
console.log(addItem(3, [{ color: "green" }]));
console.log(addItem(4, [{ color: "pink" }]));

CodePudding user response:

let arr = [{
    "id": 2,
    "color": "red"
  },
  {
    "id": 1,
    "color": "blue"
  },
  {
    "id": 2,
    "color": "yellow"
  },
];

const groupBy = (xs, key) => {
  return xs.reduce(function(rv, x) {
    const y = {...x};
    delete y[key];
    (rv[x[key]] = rv[x[key]] || []).push(y);
    return rv
  }, {})
}


const addItem = (id, colors) => {
  // const newArr = arr... etc if you don't want to modify the existing array
  arr = arr.concat(colors.map(c => {
    c.id = id;
    return c
  }))

  const grouped = groupBy(arr, 'id')
  return grouped
}

console.log(addItem(3, [{
  color: "green"
}]))
console.log(addItem(1, [{
  color: "brown"
}]))

CodePudding user response:

You may find a class useful here to encapsulate your data.

  1. On initialisation pass in your array of objects and convert it to a Map with array values. (Note: you can use an object here as an alternative).

  2. Create a method that adds new colours to the appropriate map array if they don't already exist (i.e. testing for duplicates).

const arr=[{id:2,color:"red"},{id:1,color:"blue"},{id:2,color:"yellow"}];

class ColorMap {
        
  // `reduce` over the array to create a `colors` Map.
  // If the id doesn't exist on the map as a key,
  // create it, and assign an empty array to it.
  // Then push in the color to the array if
  // it doesn't already exist
  constructor(arr) {
    this.colors = arr.reduce((acc, obj) => {
      const { id, color } = obj;
      if (!acc.has(id)) acc.set(id, []);
      if (!this.colorExists(id, color)) {
        acc.get(id).push({ color });
      }
      return acc;
    }, new Map());
  }
  
  // Simple check to see if the color already
  // exists in the target array
  colorExists(id, color) {
    return this.colors?.get(id)?.find(obj => {
      return obj.color === color;
    });
  }

  // Similar to the `reduce` function, if the id doesn't have
  // a key on the map create one, and initialise an empty array,
  // and if the color doesn't already exist add it
  addColor(id, color) {
    if (!this.colors.has(id)) this.colors.set(id, []);
    if (!this.colorExists(id, color)) {
      this.colors.get(id).push({ color });
    }
  }

  // Return the colors map as a readable object
  showColors() {
    return Object.fromEntries(this.colors);
  }

}

const colorMap = new ColorMap(arr);

colorMap.addColor(3, 'green');
colorMap.addColor(1, 'brown');
colorMap.addColor(1, 'brown');

console.log(colorMap.showColors());

Additional documentation

  • Related