jamesco
jamesco

Reputation: 83

React – Create array from arrays in Objects

Beginner React/JS question here. I have a series of entries (form submissions) that each contain arrays of languages like so:

0: {…}
dream: Array [ "Bengali", "French" ]
feel: Array [ "Arabic", "English" ]​​
speak: Array [ "Afrikaans", "Armenian" ]
think: Array [ "Albanian" ]

1: {…}
dream: Array [ "English", "French" ]
feel: Array [ "German", "Italian" ]​​
speak: Array [ "Afrikaans", "English" ]
think: Array [ "Cantonese" ]

I want an array of all languages in each category. I understand that I have to filter through each entry and save the languages, but I don't know how to check for duplicates.

Currently, I can filter to view entries a single language using

setFilter(entries.filter((key) => key.speak.includes("Afrikaans")));

but I can't figure out how to create a master list of all languages.

Upvotes: 0

Views: 2851

Answers (5)

Jadli
Jadli

Reputation: 860

try This Obj structure

var completObj=[
    {
     dream:[ "Bengali", "French" ],
     feel:[ "Arabic", "English" ],
     speak:[ "Afrikaans", "Armenian" ],
     think:[ "Albanian" ]
    },
    {
     dream:[ "English", "French" ],
     feel:[ "German", "Italian" ],
     speak:[ "Afrikaans", "English" ],
     think:[ "Cantonese" ]
    }
    ]
    var Afrikaans=completObj.filter((key) => key.speak.includes("Afrikaans"))
    
    
    console.log('Afrikaans:'+JSON.stringify( Afrikaans))
    var uniqueObj={}
    completObj.map((value, index) => {
      Object.entries(completObj[index]).forEach(([ObjKey, value]) => {
       
        if (!uniqueObj[ObjKey]) {
          uniqueObj[ObjKey] = new Set();
        }
         debugger
        value.map(list => uniqueObj[ObjKey].add(list));
        // uniqueObj[ObjKey].add(value)
      });
      
    });
    
    var dream=Array.from(uniqueObj.dream)
    
    console.log('dream unique Value:'+JSON.stringify( dream))

Upvotes: 0

Niccolò Caselli
Niccolò Caselli

Reputation: 882

Honestly, I didn't understand the question very well. But I tried to interpret it like this, let me know:

const entries = [
{
  dream:  [ "Bengali", "French" ],
  feel:   [ "Arabic", "English"],
  speak:  [ "Afrikaans", "Armenian" ],
  think:  [ "Albanian" ],
},{
  dream:  [ "English", "French" ],
  feel:   [ "German", "Italian" ],
  speak:  [ "Afrikaans", "English" ],
  think:  [ "Cantonese" ],
}
]

const fields = ["dream", "feel", "speak","think"];

const result = {};

for(field of fields){
  // create an array containing all the languages of the specific category of the for-loop (there may be duplications)
  const rawArray = entries.map(item =>  item[field]).flat();
  // delete duplicates
  const  arrayWithoutDuplicates = rawArray.filter((item,index) => rawArray.indexOf(item) === index);
  
  result[field] = arrayWithoutDuplicates;
}

console.log(result);

Upvotes: 1

Drew Reese
Drew Reese

Reputation: 203502

Given data

const data = [
  {
    dream: ["Bengali", "French"],
    feel: ["Arabic", "English"],
    speak: ["Afrikaans", "Armenian"],
    think: ["Albanian"]
  },
  {
    dream: ["English", "French"],
    feel: ["German", "Italian"],
    speak: ["Afrikaans", "English"],
    think: ["Cantonese"]
  }
];

First convert the array of category-languages arrays to a reduced object of category-language sets. The sets are used to remove duplicates.

const reducedData = data.reduce((categories, current) => {
  // Loop over the categories (dream, feel, etc..)
  // and add languages to sets
  Object.entries(current).forEach(([currentCategory, languages]) => {
    if (!categories[currentCategory]) {
      // A set will not allow duplicate entires
      categories[currentCategory] = new Set();
    }

    // Add all languages to the set
    languages.forEach(language => categories[currentCategory].add(language));
  });
  return categories;
}, {});

You now have an object with shape

{
  dream: Set("Bengali", "French", "English"), 
  feel: Set("Arabic", "English", "German", "Italian"),
  speak: Set("Afrikaans", "Armenian", "English"),
  think: Set("Albanian", "Cantonese"),
}

Then again reduce this to an object of category - languages array. This is simply converting the sets back to an array.

const reducedDataArray = Object.entries(reducedData).reduce(
  (categories, [category, languageSet]) => {
    // Convert Set back to an array
    categories[category] = [...languageSet];
    return categories;
  },
  {}
);

Result object shape

{
  dream: ["Bengali", "French", "English"], 
  feel: ["Arabic", "English", "German", "Italian"],
  speak: ["Afrikaans", "Armenian", "English"],
  think: ["Albanian", "Cantonese"],
}

const data = [
  {
    dream: ["Bengali", "French"],
    feel: ["Arabic", "English"],
    speak: ["Afrikaans", "Armenian"],
    think: ["Albanian"]
  },
  {
    dream: ["English", "French"],
    feel: ["German", "Italian"],
    speak: ["Afrikaans", "English"],
    think: ["Cantonese"]
  }
];

const reducedData = data.reduce((categories, current) => {
  Object.entries(current).forEach(([currentCategory, languages]) => {
    if (!categories[currentCategory]) {
      categories[currentCategory] = new Set();
    }
    languages.forEach(language => categories[currentCategory].add(language));
  });
  return categories;
}, {});

const reducedDataArray = Object.entries(reducedData).reduce(
  (categories, [category, languageSet]) => {
    categories[category] = [...languageSet];
    return categories;
  },
  {}
);

console.log(reducedDataArray);

Upvotes: 0

gaetan224
gaetan224

Reputation: 646

is this what you want ? you need to reduce and filter du avoid duplicates,you will have an object as result

    const myArray = [{
      dream: [ "Bengali", "French" ],
      feel: [ "Arabic", "English" ],
      speak: [ "Afrikaans", "Armenian" ],
      think: [ "Albanian" ]
    }
      ,{
        dream: [ "Bengaslis", "French" ],
        feel: [ "Arabsic", "English" ],
        speak: [ "Afrikasans", "Armenian" ],
        think: [ "Assslbanian" ]
      }
    ];

    const result = myArray.reduce((accumulator, currentValue) => {
      const dream = accumulator.dream.concat(currentValue.dream);
      const think = accumulator.think.concat(currentValue.think);
      const feel = accumulator.feel.concat(currentValue.feel);
      const speak = accumulator.speak.concat(currentValue.speak);
      accumulator.dream = dream.filter((item, pos) => dream.indexOf(item) === pos)
      accumulator.feel = feel.filter((item, pos) => feel.indexOf(item) === pos);
      accumulator.speak = speak.filter((item, pos) => speak.indexOf(item) === pos);
      accumulator.think = think.filter((item, pos) => think.indexOf(item) === pos);
      return accumulator;
    })
    
    console.log(result)

Upvotes: 2

felixmosh
felixmosh

Reputation: 35603

You can use Object.values and Object.entries in order to traversal the data object.

const data = {
  0: {
    dream: ["Bengali", "French"],
    feel: ["Arabic", "English"],
    speak: ["Afrikaans", "Armenian"],
    think: ["Albanian"],
  },

  1: {
    dream: ["English", "French"],
    feel: ["German", "Italian"],
    speak: ["Afrikaans", "English"],
    think: ["Cantonese"],
  }
};

const categoryMap = Object.values(data)
  .reduce((concatedArr, item) => concatedArr.concat(Object.entries(item)), [])
  .reduce((result, [category, values]) => {
    result[category] = result[category] || [];
    result[category] = result[category].concat(values);
    return result;
  }, {});

console.log(categoryMap);

Upvotes: 1

Related Questions