1

I have a thesaurus app, so the user may enter "dog" as a base word, and "canine,hound,mutt" as the synonyms. These are then added to a database. Along with adding "dog" as the base word, i'd like to make multiple simultaneous entries for each of the synonyms, so that the user doesn't have to go back and enter "hound" followed by "dog,canine,mutt". This would involve multiple form submissions.

Based on the above example, I want to create the following datasets before heading to the database:

var Keys = 
[
    dog,canine,mutt,hound
];

var Values = [
    [mutt,canine,hound],[dog,mutt,hound],[canine,dog,hound],[dog,canine,mutt]
];

Once I have this, I can do a simple loop through each key and grab the corresponding array within Values, and carry out my inserts. For example, when iterating based on their length, I would grab index 2 and get a key of 'mutt' and then grab the values of '[canine,dog,hound]'. So far, my attempts to perform the required nested loops to achieve this dataset haven't proved fruitful.

So far, i've tried this, and am hopeful of some suggestions:

    var baseWord = [];
    baseWord.push("dog");
    var synonyms = ["hound","mutt","canine"];
    var words = baseWord.concat(synonyms);                  
    console.log(words.length); //outputs 4

    //new arrays to hold the result of the inner loop calculation
    var Keys = [];
    var Values = [];
    for(var i = 0; i < words.length; i++){
        //removing the inner loops makes this output, the 4 values from the 'words' variable. with the inclusion of the loops, we only get back 'dog'
        keys.push(words[i]);


        for(var x = 0; x < words.length; x++){
            //I want to loop through the 'words' variable, and if current index of 'words' matches a value in tempValues(matches a different value of tempValues each time, which is what i'd want(it allows us to ignore the current key, and keep the values), then remove that particular value from tempValues, then push the remaining values in tempValues into our 'VAlues' array that we declared ouside all of these loops
            var tempValues = words;
            //console.log("tempvalues is :: %s", JSON.stringify(tempValues));
                for(var o = 0; o < words.length; o++){
                    if(words[o] === words[x]){
                        //get rid of the value in tempValues that is equals to the value of the key in the outer loop(for this particular iteration)
                        tempValues.splice(tempValues[o]);
                    }
                    console.log(JSON.stringify(tempValues));
                }
                Values.push(tempValues);
        };
    };
    console.log("the new keys array is :: %s", JSON.stringify(Keys)); //keep getting dog
    console.log("the new values array is :: %s", JSON.stringify(Values)); //keep getting [[]]
2
  • Is your PHP tag important? Commented Sep 21, 2017 at 0:45
  • No but it was the only other suggestion besides array, and I figured it would help in getting exposure to what I thought was a common problem. Commented Sep 21, 2017 at 0:47

3 Answers 3

2

Try something like this:

//OP code
var baseWord = [];
baseWord.push("dog");
var synonyms = ["hound", "mutt", "canine"];
var words = baseWord.concat(synonyms);
console.log(words.length); //outputs 4

//and new code
//put result into an object
var dictionary = {};
for (var i = 0, w; w = words[i]; ++i) {
  //take each word (w)
  dictionary[w] = words.filter(function(word) {
    return word != w; //all words except w
  });
}
//take the object
console.log(dictionary);
//or stringify it
console.log(JSON.stringify(dictionary));

//Just for OP
console.log('direct answer');
var keys = words.map(function(word) {
  return word;
});
console.log('Keys :: ' + JSON.stringify(keys));//same as "words"

var values = words.map(function(word) {
  return words.filter(function(w) {
    return word != w; //all words except w
  });
});
console.log('Values :: ' + JSON.stringify(values));

//ES6 style
console.log('ES6 style');
var keys = words.map(word => {
  return word;
});
console.log('Keys :: ' + JSON.stringify(keys));//same as "words"

var values = words.map(word => {
  return words.filter(w => {
    return word != w; //all words except w
  });
});
console.log('Values :: ' + JSON.stringify(values));

//or even All In One
console.log('All In One');
var keyValues = words.map(word => {
return [word, words.filter(w => {return word != w;})];
});
console.log(JSON.stringify(keyValues));

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

2 Comments

Great answer Alex. This is the solution i'm going to use going forward, but I think I have to give the accepted answer to Scuzzy because his solution answers the question's specifics, ie - populating the 'Keys' and 'Values' variables.
@OisinFoley Look at updated answer. No need to switch accepted answer. Just see what modern JS can do ;).
1

Here is a simple loop to build the output.

The outer loop is for your keys, and the inner loop builds a set which is pushed to your values array

var BaseWord = 'dog';
var Synonyms = ['canine','mutt','hound'];
var Keys = Synonyms;
var Values = [];

Keys.unshift( BaseWord ); // add baseword to the start of Keys

for( var i = 0; i < Keys.length; i++ )
{
  var Set = [];
  for( var j = 0; j < Keys.length; j++ )
  {
    if( Keys[j] !== Keys[i] )
    {
      Set.push( Keys[j] );
    }
  }
  Values.push( Set );
}

console.log("the new keys array is :: %s", JSON.stringify( Keys ) );
console.log("the new Values array is :: %s", JSON.stringify( Values ) );

Here is how I would do this in PHP

$BaseWord = 'dog';
$Synonyms = array('dog','canine','mutt','hound');

$keys = array( $BaseWord ) + $Synonyms;
$values = array();

foreach( $keys as $key )
{
  $values[] = array_values( array_diff( $keys, array( $key ) ) );
}

echo json_encode( $keys );
echo json_encode( $values );

1 Comment

Cheers Scuzzy. Although Alex's is the more usable solution, your answer's output perfectly matches the question.
1

Looks like @Scuzzy has an answer about how to do it. I'll let you know what you're doing wrong.

1. This

var tempValues = words;

words is an Array. That means it gets passed by reference. Which means tempValue IS words, and any edits you do to tempValue will be done to words. Which brings me to the next point:

2. You're using splice wrong

tempValues.splice(tempValues[o]);

This translates to:

tempValues.splice("dog");

On the first time through that loop. Unfortunately, Array.splice does not take a string as the first param. It takes an index. MDN doesn't document what it does if a string is passed. But it's behaving as if you put a 0.

.splice(0) means remove everything from the array starting at the 0th index. So, in your first loop through temp array it rips everything out, and then doesn't loop again (because there's nothing left to loop over). So, tempArray becomes [].

1 Comment

Thanks jlogan, I guess I need to reacquaint myself with splice's behaviour

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.