Using .reduce () in a list of objects

I have this sample data:

let list = [
  {'first': 'morgan', 'id': 1},
  {'first': 'eric', 'id': 1},
  {'first': 'brian', 'id': 2 },
  {'first': 'derek', 'id' : 2},
  {'first': 'courtney', 'id': 3},
  {'first': 'eric', 'id': 4},
  {'first': 'jon', 'id':4},
]

I try to end up with:

[[1, [morgan, eric]], [2, [brian, derek]], [3, [courtney]], [4, [eric, jon]]

I use the function .reduce()to display above the list. However, I am somewhat stuck.

I got this job:

let b = list.reduce((final_list, new_item) => {
  x = final_list.concat([[new_item.id, [new_item.first]]])
  return x
}, [])

However, this aligns the list in the list of list lists, but does not combine names that have a similar identifier.

I tried using the .map() code below does not work

I tried to display the final_list file (list [id, [names]] to see if id exists new_itemin smaller_list, and then add new_item.firstto smaller_list[1](which should be a list of names).

Is this the right approach?

let b = list.reduce((final_list, new_item) => {
  final_list.map((smaller_list) => {
    if (smaller_list.indexOf((new_item.id)) >=0) {
      smaller_list[1].concat(new_item.first)
      // not sure what to do here...
    } else {
        // not sure what to do here either...
    }

  })
  x = final_list.concat([[item.id, [item.first]]])
  return x
}, [])
+4
source share
7 answers

. Object.values .

let list = [
  {'first': 'morgan', 'id': 1},
  {'first': 'eric', 'id': 1},
  {'first': 'brian', 'id': 2 },
  {'first': 'derek', 'id' : 2},
  {'first': 'courtney', 'id': 3},
  {'first': 'eric', 'id': 4},
  {'first': 'jon', 'id':4}
];

let result = list.reduce( (acc, item, index) => {
  if(acc[item.id]){
  	acc[item.id][1].push(item.first);
  } else {
  	acc[item.id] = [item.id, [item.first]];
  }
  return acc;
}, []);

console.log(Object.values(result));
Hide result
+5

, , , , , .

let list = [
  {'first': 'morgan', 'id': 1},
  {'first': 'eric', 'id': 1},
  {'first': 'brian', 'id': 2 },
  {'first': 'derek', 'id' : 2},
  {'first': 'courtney', 'id': 3},
  {'first': 'eric', 'id': 4},
  {'first': 'jon', 'id':4},
]

let temp = [], result = [];

list.map(entry => {
    if(!temp[entry.id]) temp[entry.id] = [entry.first]
    else temp[entry.id].push(entry.first)
})
temp.forEach((names, id) => {
    result.push([id, names])
})

console.log(JSON.stringify(result))
Hide result

EDIT: temp, ID forEach. - , Hash.

+3

, ,

let list = [
  {'first': 'morgan', 'id': 1},
  {'first': 'eric', 'id': 1},
  {'first': 'brian', 'id': 2 },
  {'first': 'derek', 'id' : 2},
  {'first': 'courtney', 'id': 3},
  {'first': 'eric', 'id': 4},
  {'first': 'jon', 'id':4},
]

const idMap = list.reduce((map, item) => {
  if (Array.isArray(map[item.id])) {
    map[item.id].push(item.first)
  } else {
    map[item.id] = [item.first]
  }
  return map
}, {})

const b = Object.keys(idMap).map(id => [parseInt(id), idMap[id]])
console.info(JSON.stringify(b))
Hide result
+3

, . 3

verbose,

const tuples1 = list.reduce( (tuples, obj) => {
  if( tuples.some( ( [id, _] ) => id === obj.id ) ){
    tuples.find( ( [id, _] ) => id === obj.id )[1].push(obj.first)
  }else{
    tuples.push([obj.id, [obj.first]])
  }
  return tuples
}, [])

, tuples1, terse

const tuples2 = list.reduce( (tuples, obj) =>
  ( tuples.some( ( [id, _] ) => id === obj.id ) ) ?
    ( tuples.find( ( [id, _] ) => id === obj.id )[1].push(obj.first), tuples ) :
    ( tuples.push([obj.id, [obj.first]]), tuples ), [])

,

const tuples3 = list.reduce( (tuples, obj) => {
  const existingId = tuples.find( ( [id, _] ) => id === obj.id )
  if( existingId ){
    existingId[1].push(obj.first)
  }else{
    tuples.push([obj.id, [obj.first]])
  }
  return tuples
}, [])

[ [ 1, [ 'morgan', 'eric' ] ],
  [ 2, [ 'brian', 'derek' ] ],
  [ 3, [ 'courtney' ] ],
  [ 4, [ 'eric', 'jon' ] ] ]
+1

reduce.

. , , .

  • list Id.

  • Id . , .

  • Id .
  • first .
  • . result.

, , , IDE.

var list = [
    {'first': 'morgan', 'id': 1},
    {'first': 'eric', 'id': 1},
    {'first': 'brian', 'id': 2 },
    {'first': 'derek', 'id' : 2},
    {'first': 'courtney', 'id': 3},
    {'first': 'eric', 'id': 4},
    {'first': 'jon', 'id':4},
]

var result = [];
var keyById = {};

// Sort the list of items to be keyed by: Id => [ item, item ]
list.forEach(function(item) {
    if (!keyById.hasOwnProperty(item.id)) {
        keyById[item.id] = [];
    }
    keyById[item.id].push(item);
});

// Build the data structure
for (var id in keyById) {
    var item = []; // The outer element
    var nestedItem = []; // The nested element belonging to the outer
    item.push(id);
    keyById[id].forEach(function(element) {
        nestedItem.push(element.first);
    });
    item.push(nestedItem);
    result.push(item); 
}

console.log(JSON.stringify(result, '', 2));
Hide result
0

,

  • list id key value array first.
  • list ( ).
  • , array id, - - array value, id, push list > ( array list).

var list = [
      {'first': 'morgan', 'id': 1},
      {'first': 'eric', 'id': 1},
      {'first': 'brian', 'id': 2 },
      {'first': 'derek', 'id' : 2},
      {'first': 'courtney', 'id': 3},
      {'first': 'eric', 'id': 4},
      {'first': 'jon', 'id':4},
    ],
    o = {}, p;

list.forEach( ( v ) => {
    if ( !o[ v.id ] ) {
        o[ v.id ] = [];
    }
    o[ v.id ].push( v.first );
} );

list = []; // if overwriting

for ( p in o ) {
    if ( o.hasOwnProperty( p ) ) {
        list.push( [ parseInt( p ), o[ p ] ] );
    }
}

console.log( JSON.stringify( list ).replace( /,/g, ", " ) );
Hide result

Edited to add parseInt()(seen in another answer), as the expected output of the question does show the numbers as integers, not strings.
And changed the demo output to stringifyed JSON(also noticed (easier to read) in other answers).

0
source

Perhaps the easiest way is to write a simple loop for this:

let final_list = []
for (k = 0; k < list.length; k += 2) {
    let item1 = list[k]
    let item2 = list[k + 1]
    final_list.push([item1.id, [item1.first, item2.first]])
}
-2
source

Source: https://habr.com/ru/post/1680922/


All Articles