5

i have arrays, 1 array is master data and other array which contains pipe seperated value. please find below the code for the same

var master = [
{id:1, value:'John'},
{id:2, value:'Bobby'}
];

var names = [
{id:1, name:'Sandra|John', type:'user', username:'sandraJ'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter|John', type:'user', username:'peteJ'},
{id:4, name:'Bobby', type:'user', username:'be_bob'},
{id:4, name:'Peter1|John1', type:'user', username:'be_bob'}
];

The resultant output should be the following

var result3 = [
{id:1, name:'Sandra'},
{id:2, name:'Peter'},
{id:2, name:'Peter1|John1'}
];

I tried following ES6 version but it does not throw the expected output.

let result = names.filter(o1 => !master.some(o2 => 
o1.name.split('|').includes(o2.value)));

i also tried replacing some with every, but still it doesn't work

let result = names.filter(o1 => !master.every(o2 => 
o1.name.split('|').includes(o2.value)));

can someone please help me with the same?

7
  • 1
    I don't really understand your resultant data? Can you check if your example is correct and explain a bit more what you are trying to do? Commented Aug 24, 2018 at 11:22
  • where do you get the id from, what happens with name? Commented Aug 24, 2018 at 11:22
  • Please, explain what You would like to have in result array. Commented Aug 24, 2018 at 11:24
  • my resultant output should be non matching data in my array 2 var result3 = [ {id:1, name:'Sandra'}, {id:2, name:'Peter'}, {id:2, name:'Peter1|John1'} ]; Commented Aug 24, 2018 at 11:28
  • Wait, is the rule that if a name exists i master, any other names including that name have to be split? Hence Peter1|John1 stays, but the contractions of x|John don't? Commented Aug 24, 2018 at 11:29

4 Answers 4

4

This does assume that the ids in the result aren't correct, since I have no idea otherwise how Peter|John and Peter1|John1 change their id to 2.

const master = [
  {id:1, value:'John'},
  {id:2, value:'Bobby'}
];
const names = [
  {id:1, name:'Sandra|John', type:'user', username:'sandraJ'},
  {id:2, name:'John', type:'admin', username:'johnny2'},
  {id:3, name:'Peter|John', type:'user', username:'peteJ'},
  {id:4, name:'Bobby', type:'user', username:'be_bob'},
  {id:4, name:'Peter1|John1', type:'user', username:'be_bob'}
];
// map the valid names for easier access
const valid_names = master.map(({ value }) => value );
// We could map => filter instead if that's clearer.
const invalid_items = names.reduce(( invalid_items, item ) => {
  // Get all the diferent names inside the item.
  const item_names = item.name.split( '|' );
  // Filter out all the valid names
  const invalid_names = item_names.filter( name => !valid_names.includes( name ));
  // If there are invalid names remaining, create a new object.
  // No idea how the "id" property should be transformed.
  if ( invalid_names.length ) {
    invalid_items.push({
      id: item.id,
      name: invalid_names.join( '|' )
    });
  }
  return invalid_items;
}, [] );
console.log( invalid_items );

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

Comments

3

Here is a version using filter and findIndex.

const master = [
  {id:1, value:'John'},
  {id:2, value:'Bobby'}
];

const names = [
  {id:1, name:'Sandra|John', type:'user', username:'sandraJ'},
  {id:2, name:'John', type:'admin', username:'johnny2'},
  {id:3, name:'Peter|John', type:'user', username:'peteJ'},
  {id:4, name:'Bobby', type:'user', username:'be_bob'},
  {id:4, name:'Peter1|John1', type:'user', username:'be_bob'}
];

//This step, if you wish that the original data should not be mutated.
const namesCopy = Object.assign([], names);

//Filter through the names
const result = namesCopy.filter(obj=>{

  //Split the name if there is a |
  const split = obj.name.split("|");

  //Create a new name without the master names in it
  const newName = split.filter(name=>{
    //check to see if the master name exists within the name
    return master.findIndex(obj2=>obj2.value === name) === -1;
  }).join("|"); // Join them together as a string if there is more than one name left
  
  //If newName is empty then we can assume that master names existed in this object
  if(newName.length === 0) return false;
  
  //otherwise update the name with newName
  obj.name = newName;
  return true;
});

console.log(result);

2 Comments

this mutates the original data.
@NinaScholz is that better? Otherwise I don't know how I should go about it.
1

How about something like this?

using .map, .filter and for loop.

var master = [
{id:1, value:'John'},
{id:2, value:'Bobby'}
];

var names = [
{id:1, name:'Sandra|John', type:'user', username:'sandraJ'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter|John', type:'user', username:'peteJ'},
{id:4, name:'Bobby', type:'user', username:'be_bob'},
{id:4, name:'Peter1|John1', type:'user', username:'be_bob'}
];

let yFilter = master.map(itemY => { return itemY.value; });
let filteredX = names.filter(itemX => !yFilter.includes(itemX.name));

var processed = [];

for(var i = 0; i < filteredX.length; i++){
	var item = filteredX[i];
  var contains = master.filter(function(x){ return item.name.split("|").indexOf(x.value) > -1; });
  
  if(contains.length > 0){
  	item.name = item.name.substring(0, item.name.indexOf(contains[0].value) - 1);
  }
  processed.push(item);
}

console.log(processed);

Comments

1

You could map the objects with the filtered names and filter then by length of the names. At the end map new objects with updated name property.

var master = [{ id: 1, value: 'John' }, { id: 2, value: 'Bobby' }],
    names = [{ id: 1, name: 'Sandra|John', type: 'user', username: 'sandraJ' }, { id: 2, name: 'John', type: 'admin', username: 'johnny2' }, { id: 3, name: 'Peter|John', type: 'user', username: 'peteJ' }, { id: 4, name: 'Bobby', type: 'user', username: 'be_bob' }, { id: 4, name: 'Peter1|John1', type: 'user', username: 'be_bob' }],
    result = names
        .map((s => o =>
            [o, o.name.split('|').filter(n => !s.has(n)).join('|')]
        )(new Set(master.map(({ value }) => value))))
        .filter(([, { length }]) => length)
        .map(([o, name]) => Object.assign({}, o, { name }));

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

Comments

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.