0

I have array like this, my id and name will be same for multiple objects but organizations values can be different

array= [
  {id: 1, name: "Test1", organizations: 1},
  {id: 1, name: "Test1", organizations: 2},
  {id: 1, name: "Test1", organizations: 3},
  {id: 2, name: "Test2", organizations: 4},
  {id: 2, name: "Test2", organizations: 5},
  {id: 2, name: "Test2", organizations: 6} 
];

I want to convert this to be like this:

expectedArray =  [
  {id: 1, name: "Test1", organizations: [1,2,3]},
  {id: 2, name: "Test2", organizations: [4,5,6]} 
];

Can someone please help

2

9 Answers 9

3

const array= [
  {id: 1, name: "Test1", organizations: 1},
  {id: 1, name: "Test1", organizations: 2},
  {id: 1, name: "Test1", organizations: 3},
  {id: 2, name: "Test2", organizations: 4},
  {id: 2, name: "Test2", organizations: 5},
  {id: 2, name: "Test2", organizations: 6} 
];

const mergeDuplicates= (field, uniqueField) => (source = [], value)=> {
    const target = source.find( item => item[uniqueField] == value[uniqueField] );
    if(target) target[field].push( value[field] );
    else source.push({...value, [field]: [ value[field] ] });
    return source;
}
const mergeOrganaizationsById = mergeDuplicates('organizations','id')
const result = array.reduce(mergeOrganaizationsById, [])
console.log(result)

1

You'll want to reduce.

array.reduce((acc, cur) => {
  const i = acc.findIndex(a => a.id === cur.id && a.name === cur.name);
  if (i === -1) return [...acc, {...cur, organizations: [cur.organizations]}];
  return [...acc.slice(0, i), {...cur, organizations: [...acc[i].organizations, cur.organizations]}, ...acc.slice(i +1)];
}, []);
1

You can achieve the output using forEach by grouping based on name and then pushing the necessary fields into the output array.

const array = [
  { id: 1, name: "Test1", organizations: 1 },
  { id: 1, name: "Test1", organizations: 2 },
  { id: 1, name: "Test1", organizations: 3 },
  { id: 2, name: "Test2", organizations: 4 },
  { id: 2, name: "Test2", organizations: 5 },
  { id: 2, name: "Test2", organizations: 6 }
];

const current = Object.create(null);
const finalArr = [];
array.forEach(function (o) {
  if (!current[o.name]) {
   current[o.name] = [];
   finalArr.push({ id: o.id, name: o.name, organizations: current[o.name] });
  }
  current[o.name].push(o.organizations);
});
console.log(finalArr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1

Another one solution in kind of ES6 style

const array= [{id: 1, name: "Test1", organizations: 1},{id: 1, name: "Test1", organizations: 2},{id: 1, name: "Test1", organizations: 3},{id: 2, name: "Test2", organizations: 4},{id: 2, name: "Test2", organizations: 5},{id: 2, name: "Test2", organizations: 6}];

const result =  Object.values(array.reduce((acc, { id, name, organizations }) => {
  const hash = `${id}-${name}`;
  acc[hash] = acc[hash] 
    ? { ...acc[hash], organizations: [...acc[hash].organizations, organizations] } 
    : { id, name, organizations: [organizations] };
  return acc;
}, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1
  • I like this solution best. The only thing you'll have to look out for is the hash construction, if there are dashes in either field you can end up with false matches.
    – windowsill
    Commented Dec 25, 2021 at 3:49
0

I think it may be the easiest way to tackle this problem, only using the forEach and basic arrays' method.

I hope I answered your question.

const array = [
  { id: 1, name: "Test1", organizations: 1 },
  { id: 1, name: "Test1", organizations: 2 },
  { id: 1, name: "Test1", organizations: 3 },
  { id: 2, name: "Test2", organizations: 4 },
  { id: 2, name: "Test2", organizations: 5 },
  { id: 2, name: "Test2", organizations: 6 }
];

const newArr = [];

// for keeping track for added item
const addedItems = [];

// for keeping track of added item idx
let addedItemIdx = 0;

array.forEach((item) => {
  if (!addedItems.includes(item.id)) {
    let tempOrg = item.organizations;
    newArr.push({ ...item, organizations: [tempOrg] });
    addedItems.push(item.id);
    addedItemIdx++;
  } else {
    newArr[addedItemIdx - 1].organizations.push(item.organizations);
  }
});
console.log(newArr);

0

What you are looking for is called a hashmap. You can read about them but the basic idea is that you make a key,value pair and access to the data with keys is very efficient(O(1) amortized). So here is one way to solve this problem in python. I am sure you can use it to solve it in your language.

    array= [
  {"id": 1, "name": "Test1", "organizations": 1},
  {"id": 1, "name": "Test1", "organizations": 2},
  {"id": 1, "name": "Test1", "organizations": 3},
  {"id": 2, "name": "Test2", "organizations": 4},
  {"id": 2, "name": "Test2", "organizations": 5},
  {"id": 2, "name": "Test2", "organizations": 6}
]
# Initilize a hashmap
hash_map = {}
# Loop over all the items in array and create the hashmap
for item in array:
    # key will be id and name as both are needed to group the organizations
    # We have use comma to separate them as we assume that name or id cannot have comma
    key = str(item["id"])+","+item["name"]
    # IF key is already present then add the new organizations id to it
    if key in hash_map:
        hash_map[key].append(item["organizations"])
    # Else make a new list with the current organizations id
    else:
        hash_map[key] = [item["organizations"]]

# Create the expected array
expected_array = []
for key,value in hash_map.items():
    # Get the id and name by spliting the key that we created 
    idx,name = key.split(",")
    expected_array.append({"id":idx,"name":name,"organizations":value})
print(expected_array)
0

const array = [
  { id: 1, name: "Test1", organizations: 1 },
  { id: 1, name: "Test1", organizations: 2 },
  { id: 1, name: "Test1", organizations: 3 },
  { id: 2, name: "Test2", organizations: 4 },
  { id: 2, name: "Test2", organizations: 5 },
  { id: 2, name: "Test2", organizations: 6 }
];

const result=array.reduce((acc,curr)=>{
  const id=curr.id;
  const {organizations}=curr;
   const findIndex=acc.findIndex(item=> item.id===curr.id)
  if(findIndex===-1){
    acc.push({...curr,organizations:[organizations]});
  } else {
   
    acc[findIndex].organizations.push(curr.organizations)
  }
  return acc;
},[]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0

This should work

const array = [{
    id: 1,
    name: "Test1",
    organizations: 1
  },
  {
    id: 1,
    name: "Test1",
    organizations: 2
  },
  {
    id: 1,
    name: "Test1",
    organizations: 3
  },
  {
    id: 2,
    name: "Test2",
    organizations: 4
  },
  {
    id: 2,
    name: "Test2",
    organizations: 5
  },
  {
    id: 2,
    name: "Test2",
    organizations: 6
  }
];
const reducedArray = array.reduce((resultArray, arrayElement) => {
  const elementIndex = resultArray.findIndex(element => element.id === arrayElement.id);

  if (elementIndex !== -1) {
    resultArray[elementIndex].organizations.push(arrayElement.organizations)
  } else {
    resultArray.push({
      ...arrayElement,
      organizations: [arrayElement.organizations],
    });
  }
  return resultArray;
}, []);

console.log(reducedArray)

0

const array = [{
    id: 1,
    name: "Test1",
    organizations: 1
  },
  {
    id: 1,
    name: "Test1",
    organizations: 2
  },
  {
    id: 1,
    name: "Test1",
    organizations: 3
  },
  {
    id: 2,
    name: "Test2",
    organizations: 4
  },
  {
    id: 2,
    name: "Test2",
    organizations: 5
  },
  {
    id: 2,
    name: "Test2",
    organizations: 6
  }
];


const formattedData = array.reduce((result, {
  id,
  name,
  organizations
}) => {
  let filteredRow = result.find(row => row.id === id && row.name === name);
  const org = filteredRow ? filteredRow.organizations : [];
  org.push(organizations);
  filteredRow = {
    id,
    name,
    organizations: org
  };
  if (org.length === 1) result.push(filteredRow);
  return result;
}, [])

console.log(formattedData)

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Dec 24, 2021 at 8:04

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.